- 打卡等级:初来乍到
- 打卡总天数:2
- 最近打卡:2026-02-04 09:04:13
已绑定手机
新手上路
- 积分
- 16
|
发表于 2026-2-4 14:44:43
|
显示全部楼层
#include "reg51.h"
#include "intrins.h"
sfr T2L = 0xd7;
sfr T2H = 0xd6;
sfr AUXR = 0x8e;
sfr P_SW1 = 0xA2;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P3M0 = 0xB2;
sfr P3M1 = 0xB1;
// IAP/EEPROM ?????????STC8?????
sfr IAP_DATA = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
sfr IAP_CMD = 0xC5;
sfr IAP_TRIG = 0xC6;
sfr IAP_CONTR = 0xC7;
sfr IAP_TPS = 0xF5;
// ?????????????reg51.h???????
// TMOD, TL0, TH0, TR0, TF0, ET0 ????8051?????
sbit LED = P1^0;
sbit FM_IN1 = P3^4;
sbit FM_IN2 = P3^3;
sbit UART_TX = P3^7;
sbit UART_RX = P3^6;
unsigned char flag = 0;
unsigned char device_addr = 0x01;
// ???????
unsigned char rx_buffer[4];
unsigned char rx_len = 0;
volatile bit rx_complete = 0;
// ???????
unsigned char code KAI[4] = {0x01, 0x03, 0xFF, 0xAA};
unsigned char code GUAN[4] = {0x01, 0x03, 0x00, 0xAA};
// ????????
volatile unsigned char pending_action = 0;
// EEPROM ???????
#define EEPROM_ADDR_BASE 0x0000
#define DEVICE_ADDR_OFFSET 0x00
#define FOSC 20000000UL
#define BAUD 9600
// IAP ??????
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
// ==================== ??????????? ====================
// ???????????? 1ms??????
volatile unsigned int sys_tick = 0;
// ???????????????????????bit?????
typedef struct {
unsigned int start; // ??????
unsigned int delay; // ??????(ms)
unsigned char active; // ????? (0=??, 1=????)
unsigned char timeout; // ???? (0=????, 1=????)
} SoftTimer;
// ?????????????
SoftTimer timer_led; // LED????????
SoftTimer timer_fm; // ????????????
// ?????????????
void Timer_Start(SoftTimer *timer, unsigned int ms)
{
timer->start = sys_tick;
timer->delay = ms;
timer->active = 1;
timer->timeout = 0;
}
// ????????????????????
unsigned char Timer_IsTimeout(SoftTimer *timer)
{
if(!timer->active) return 0;
if((sys_tick - timer->start) >= timer->delay)
{
timer->active = 0;
timer->timeout = 1;
return 1;
}
return 0;
}
// ???????
void Timer_Stop(SoftTimer *timer)
{
timer->active = 0;
timer->timeout = 0;
}
// ????????????????EEPROM??????
void Delay_ms(unsigned int ms)
{
unsigned int start = sys_tick;
while((sys_tick - start) < ms);
}
// =====================================================
// IAP ????
void IapIdle(void)
{
IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0x80;
IAP_ADDRL = 0;
}
// ?? EEPROM ?????????
unsigned char IapReadByte(unsigned int addr)
{
unsigned char dat;
IAP_CONTR = 0x80;
IAP_TPS = 20;
IAP_CMD = CMD_READ;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
dat = IAP_DATA;
IapIdle();
return dat;
}
// ?? EEPROM ?????????
void IapProgramByte(unsigned int addr, unsigned char dat)
{
IAP_CONTR = 0x80;
IAP_TPS = 20;
IAP_CMD = CMD_PROGRAM;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
// ???? EEPROM ????
void IapEraseSector(unsigned int addr)
{
IAP_CONTR = 0x80;
IAP_TPS = 20;
IAP_CMD = CMD_ERASE;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
// ??????????? EEPROM
void SaveDeviceAddr(unsigned char addr)
{
IapEraseSector(EEPROM_ADDR_BASE);
Delay_ms(10);
IapProgramByte(EEPROM_ADDR_BASE + DEVICE_ADDR_OFFSET, addr);
Delay_ms(5);
}
// ?? EEPROM ????????
unsigned char LoadDeviceAddr(void)
{
unsigned char addr;
addr = IapReadByte(EEPROM_ADDR_BASE + DEVICE_ADDR_OFFSET);
if(addr == 0xFF) addr = 0x01;
return addr;
}
// ??????? - ????????
void On_FM_Start(void)
{
FM_IN1 = 0;
FM_IN2 = 1;
Timer_Start(&timer_fm, 150);
}
void Off_FM_Start(void)
{
FM_IN1 = 1;
FM_IN2 = 0;
Timer_Start(&timer_fm, 150);
}
void FM_Stop(void)
{
FM_IN2 = 0;
FM_IN1 = 0;
}
// LED????????
typedef enum {
LED_STATE_IDLE = 0,
LED_STATE_BLINK_ON = 1,
LED_STATE_BLINK_OFF = 2
} LED_State;
LED_State led_state = LED_STATE_IDLE;
unsigned char led_blink_count = 0;
unsigned char led_blink_target = 0;
unsigned int led_on_time = 0;
unsigned int led_off_time = 0;
// LED???? - ????????????????
void LED_Control(void)
{
switch(flag)
{
case 0: // ???????500ms????30s
if(led_state != LED_STATE_IDLE)
{
led_state = LED_STATE_IDLE;
Timer_Stop(&timer_led);
}
if(!timer_led.active)
{
LED = 1;
Timer_Start(&timer_led, 500);
}
else if(Timer_IsTimeout(&timer_led))
{
if(LED == 1)
{
LED = 0;
Timer_Start(&timer_led, 30000);
}
else
{
LED = 1;
Timer_Start(&timer_led, 500);
}
}
break;
case 1: // ???2?????500ms????500ms??
case 2: // ???5?????250ms????250ms??
if(led_state == LED_STATE_IDLE)
{
led_blink_count = 0;
led_blink_target = (flag == 1) ? 2 : 5;
led_on_time = (flag == 1) ? 500 : 250;
led_off_time = (flag == 1) ? 500 : 250;
LED = 1;
led_state = LED_STATE_BLINK_ON;
Timer_Start(&timer_led, led_on_time);
}
else if(Timer_IsTimeout(&timer_led))
{
if(led_state == LED_STATE_BLINK_ON)
{
LED = 0;
led_state = LED_STATE_BLINK_OFF;
Timer_Start(&timer_led, led_off_time);
}
else if(led_state == LED_STATE_BLINK_OFF)
{
led_blink_count++;
if(led_blink_count >= led_blink_target)
{
flag = 0;
led_state = LED_STATE_IDLE;
led_blink_count = 0;
}
else
{
LED = 1;
led_state = LED_STATE_BLINK_ON;
Timer_Start(&timer_led, led_on_time);
}
}
}
break;
}
}
void UART_SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
void UART_SendArray(unsigned char *buf, unsigned char len)
{
unsigned char i;
for(i = 0; i < len; i++)
UART_SendByte(buf[i]);
}
void UART_SendConst(const unsigned char *buf)
{
UART_SendByte(buf[0]);
UART_SendByte(buf[1]);
UART_SendByte(buf[2]);
UART_SendByte(buf[3]);
}
void UART_Init(void)
{
P1M0 |= 0x01; P1M1 &= 0xFE;
P3M0 |= 0x18; P3M1 &= 0xE7;
P3M0 |= 0x80; P3M1 &= 0x7F;
P3M0 &= 0xBF; P3M1 |= 0x40;
P_SW1 = 0x40;
SCON = 0x50;
T2L = (65536 - FOSC/4/BAUD) & 0xFF;
T2H = (65536 - FOSC/4/BAUD) >> 8;
AUXR = 0x15;
TI = 1;
ES = 1;
EA = 1;
}
// ?????0????? - 1ms??? @20MHz
void Timer0_Init(void)
{
AUXR |= 0x80; // T0x12=1, 1T??
TMOD &= 0xF0; // ???T0?????
TMOD |= 0x00; // ??0??16????????
// 20MHz / 1T = 20M????/??1ms = 20000????
// ??? = 65536 - 20000 = 45536 = 0xB1E0
TH0 = 0xB1;
TL0 = 0xE0;
TF0 = 0;
ET0 = 1; // ????T0???
TR0 = 1; // ????T0
}
// ?????0??? - 1ms
void Timer0_ISR(void) interrupt 1
{
sys_tick++;
}
void UART_ISR(void) interrupt 4
{
if(RI)
{
RI = 0;
if(rx_len < 4)
rx_buffer[rx_len++] = SBUF;
if(rx_len == 4)
{
if(SBUF == 0xAA && rx_buffer[0] == device_addr)
{
rx_complete = 1;
}
else
{
rx_len = 0;
}
}
else if(rx_len > 4)
{
rx_len = 0;
}
}
if(TI) TI = 0;
}
void main(void)
{
unsigned char cmd;
unsigned char param;
UART_Init();
Timer0_Init();
device_addr = LoadDeviceAddr();
LED = 1;
rx_len = 0;
while(1)
{
if(rx_complete)
{
rx_complete = 0;
cmd = rx_buffer[1];
param = rx_buffer[2];
rx_len = 0;
switch(cmd)
{
case 0x03:
if(param == 0xFF)
{
pending_action = 1;
flag = 1;
UART_SendConst(KAI);
}
else if(param == 0x00)
{
pending_action = 2;
flag = 1;
UART_SendConst(KAI);
}
break;
case 0x05:
device_addr = param;
SaveDeviceAddr(param);
flag = 2;
UART_SendConst(KAI);
break;
}
}
if(pending_action == 1)
{
pending_action = 0;
On_FM_Start();
}
else if(pending_action == 2)
{
pending_action = 0;
Off_FM_Start();
}
if(Timer_IsTimeout(&timer_fm))
{
FM_Stop();
}
LED_Control();
}
}
这是新的程序 发送uint8_t e2[4]={0X01,0X05,0X03,0XAA};
刚开始成功,但是串口没返回
发送完以后在发送uint8_t e2[4]={0X01,0X05,0X03,0XAA};
这时候不成功是对的,确实未成功,但是把第一次该返回的内容这次返回了出来,感觉像缓冲区错位了 |
|