第一次接触完整的项目,虽然是个虽然是个简单的8位机,但还是遇到了挺多问题,在调试过程中出现了各种各样的麻烦,总的来说还是经验太少,暂且在这里将自己遇到的错误点记下来,方便自己以后反省
相应的串口I/O等配置
/**********pa6,pa7为TX RX***********/
_pa7 = 1;
_pa6 = 1;
_pac7 = 0;
_pac6 = 1;
_pas1 = 0b11110000; //TX RX
/********************* uart0 使用外接晶振11.0592M ********************************/
_u0cr1 = 0b10000000;
_u0cr2 = 0b11101100;
_brg0 = 5; //115200
_ur0e = 1;
_ur0f = 0;
_mf5e = 1;
_mf5f = 0;
uart.h
#ifndef _UART_H_
#define _UART_H_
#define STX 0x5A //起始位
#define EOT 0xA5 //终止位
#define TM_RXBUF_SIZE 126 //合泰bank限制,最大只能为127
#define TM_TXBUF_SIZE 32
typedef struct _TM_RXBUF
{
volatile uint8_t inpost;
volatile uint8_t outpost;
uint8_t rdata_buf[TM_RXBUF_SIZE];
}TM_RXBUF;
/*****************合泰指定bank固定写法************/
static volatile unsigned char sdata_buf1[20] __attribute__((at(0x1380)));
static volatile unsigned char sdata_buf2[20] __attribute__((at(0x1394)));
static volatile unsigned char sdata_buf3[20] __attribute__((at(0x13A8)));
static volatile unsigned char sdata_buf4[20] __attribute__((at(0x13BC)));
static volatile unsigned char temporary_buff[20] __attribute__((at(0x13D0)));
void init_tm_buf(void);
void Send_Byte(uint8_t s);
void Send_Array(uint8_t * buff,uint8_t len);
uint16_t crc_16(uint8_t *data, uint16_t len); //crc check
void cmd_protocol_handle(void);
#endif
uart.c
#include "uart.h"
/**
* @brief 发送单个字符
* @param S : 字符
* @retval 无
*/
void Send_Byte(uint8_t data)
{
while((_tidle0 == 0)&&(_txif0 ==0));
_txr_rxr0 = data;
}
/**
* @brief 发送数组
* @param buff:数组 len:数组长度
* @retval 无
*/
void Send_Array(uint8_t * buff,uint8_t len)
{
uint8_t ii;
for(ii=0;ii<len;ii++)
{
Send_Byte(*buff++);
}
Send_Byte(0xAA);
}
/**
* @brief 初始化uart接收数据数组,接受数组为环形数组,参考链表写的
* @param 无
* @retval 无
*/
void init_tm_buf(void)
{
uint16_t ii;
tm_rxbuf.inpost = 0;
tm_rxbuf.outpost = 0;
for(ii = 0; ii < TM_RXBUF_SIZE; ii++)
{
tm_rxbuf.rdata_buf[ii] = 0x00;
}
}
/**
* @brief 串口中断函数,为固定格式
* @param buff:数组 len:数组长度
* @retval 无
*/
DEFINE_ISR(UART0,0x3C)
{
//_emi = 0;
_ur0f = 0;
while(_rxif0 == 0);
tm_rxbuf.rdata_buf[tm_rxbuf.inpost] = _txr_rxr0;
//tm_rxbuf.inpost = (tm_rxbuf.inpost + 1) % 126; //不能这么写,虽然没错,但是这么写会导致接收数据时数据丢失,合泰的坑
tm_rxbuf.inpost++;
if(tm_rxbuf.inpost>125)
{
tm_rxbuf.inpost =0;
}
// _emi = 1;
}
/**
* @brief compare rdata segment is ok?
* @param buf:定时处理数据,将环形数组一直读取,直到有我们要的数据,写到buf里面
* @retval
*/
static uint8_t get_RxFE_buf( volatile unsigned char *buf)
{
uint8_t ed_4e, dataleng, ii,rdata_len,crc16_len,shifting;
uint8_t RX_omit;
uint8_t crc16_buf[60];
uint16_t crc16_compare = 0;
ed_4e = tm_rxbuf.inpost;
dataleng = ed_4e >= tm_rxbuf.outpost ? (ed_4e-tm_rxbuf.outpost) : (TM_RXBUF_SIZE - tm_rxbuf.outpost + ed_4e);
if(dataleng < 12)
{
//LED1 ^=1;
return 0; //no data ro enufu need to process
}
for(ii = 0; ii < 9; ii++)
{
buf[ii] = tm_rxbuf.rdata_buf[(tm_rxbuf.outpost + ii) % TM_RXBUF_SIZE];
}
if(buf[0] == STX)
{
shifting = buf[8];
rdata_len = (buf[8]+11);
crc16_len = (buf[8]+8);
if(rdata_len > dataleng )//data not full
{
return 0;
}
else if(buf[1] != 0x02)
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + 1) % TM_RXBUF_SIZE;
return 0;
}
else
{
for(ii = 0; ii < rdata_len; ii++)
{
buf[9 + ii] = tm_rxbuf.rdata_buf[(tm_rxbuf.outpost + 9 + ii) % TM_RXBUF_SIZE];
}
for(RX_omit=1;RX_omit<rdata_len;RX_omit++) //针对数据缺失的情况
{
if(buf[RX_omit]==STX)
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + 1) % TM_RXBUF_SIZE;
return 0;//no find the head star from next one
}
}
crc16_compare = buf[shifting+9];
crc16_compare = crc16_compare << 8;
crc16_compare |= buf[shifting+10];
/* if(buf[rdata_len] != EOT)
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + rdata_len) % TM_RXBUF_SIZE;
return 0;
}*/
for(ii = 1;ii<=crc16_len; ii++)
{
crc16_buf[ii-1] = buf[ii];
}
if(crc_16(crc16_buf, crc16_len) != crc16_compare)
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + 1) % TM_RXBUF_SIZE;
return 0;//no find the head star \ next one
}
else// have find an ok packger
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + rdata_len) % TM_RXBUF_SIZE;
return (rdata_len +1);
}
}
}
else
{
tm_rxbuf.outpost = (tm_rxbuf.outpost + 1) % TM_RXBUF_SIZE;
return 0;//no find the head star from next one
}
}
static volatile unsigned char read_ack_len __attribute__((at(0x1492)));
/**
* @brief 判断数据,以及数据处理
* @param 无
* @retval 无
*/
void cmd_protocol_handle(void)
{
read_ack_len = get_RxFE_buf(temporary_buff); //判断是否有数据进来,进来的数据是否为想要的
if(read_ack_len <= 0) //错误数据
{
return;
}
else{
//进行对的数据处理
}
}