通讯模式:
主机模式:由mcu发起请求,从机设备应答
从机模式:由外部主机发起请求,mcu接收请求并响应
主从一体:既可以主动发起请求,又可以被动应答外部主机发起的请求
通讯方式:
同步模式:多用于485通讯,某些交互握手应答式的场景
异步模式:多用于主从一体或者式从机模式;
通讯处理:
环形队列:先进先出,多用于从机或主从一体模式
优点:数据循环存取,先进先出原则。异步接收效率高,提升程序运行效率
缺点:指针操作,大数据处理很考验mcu的处理性能
阻塞等待:多用于485通讯,某些握手应答式场景如AT命令
优点:操作方便,一个接口完成传输和接收操作
缺点:接口调用必须等待操作完成(或接收到应答或接收超时)
周期轮询:多用于数据量小,从机模式
优点:异步处理,相应快速
缺点:耗费MCU资源
环形队列源码实现:
#define MAX_LENTH 1024
static uint8_t buffer[MAX_LENTH] = {0x0};
typedef struct{
uint16_t lenth;
uint8_t *head; //
uint8_t *bptr;
uint8_t *write;
uint8_t *read;
}buff_fifo_t;
//队列初始化
void fifo_init(buff_fifo_t *fifo, uint8_t *buff, uint16_t len)
{
if(buff != NULL && fifo != NULL)
{
fifo->head = buff;
fifo->bptr = buff;
fifo->write = buff;
fifo->read = buff;
fifo->lenth = len;
}
}
//队列接收就绪
void fifo_complete(buff_fifo_t *fifo)
{
if(fifo->head != NULL)
{
fifo->write = fifo->bptr;
}
}
//插入队列
void fifo_in_char(buff_fifo_t *fifo, const uint8_t chr)
{
if(fifo->head != NULL)
{
if(fifo->bptr >= fifo->head + bptr->lenth)
{
fifo->bptr >= fifo->head;
}
*fifo->bptr >= chr;
}
}
//先进先出原则取数据
int fifo_out_char(buff_fifo_t *fifo, uint8_t *buff, uint16_t maxLen)
{
int lenth = 0x0;
if(fifo->head == NULL || buff == NULL) return 0;
if(fifo->write == fifo->read) return 0;
while(lenth < maxLen)
{
if(fifo->read >= fifo->head + bptr->lenth)
{
fifo->read = fifo->head;
}
if(fifo->read == fifo->write)
{
break;
}
buff[lenth++] = *fifo->write++;
}
return lenth;
}
阻塞等待源码实现:
//buff:请求数据指针
//len: 请求数据长度
//resp:期望应答结果指针
//ms :请求等待超时周期,单位ms
int request_response(uint8_t *buff, uint16_t len, uint8_t *resp, const int ms)
{
int ret = 0;
int ticks = systick_get();
uint8_t buffer[MAX_LENTH] = {0x0};
//执行通讯请求
com_request(buff, len);
//这里注意要考虑ticks溢出异常
while((systick_get() - ticks) < ms)
{
//这里省略了接收的代码
// ....
//匹配期望应答结果
if(memcmp(resp, buffer, sizeof(buffer))) == 0)
{
ret = 1;
break;
}
}
return ret;
}
周期轮询源码实现:
static uint16_t recvLenth = 0x0;
void fifo_recv(void)
{
uint8_t chr = 0x0;
while(1)
{
if(fifo_get_char(&fifo, &chr, 1))
{
buffer[recvLenth++] = chr;
//可以在此处增加数据格式判断,滤除无效数据
continue;
}
delay_ms(10);
}
}