应用场景:
主频不高非操作系统的单片机,需要在while循环中发送 数据到上位机,当数据较长时,会让发送的过程会让其他操作有卡顿感。为了解决这个问题,需采用一种方法:在每次大循环中只发一个字节数据,直到发送完毕。
#include <stdio.h>
#include <unistd.h>
void msleep(int ms)
{
usleep(1000*ms);
}
//=============================================
#define MAX_SEND_LEN 10
u8 g_sendBuffer1[MAX_SEND_LEN]={ 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa };
u8 g_sendBuffer2[MAX_SEND_LEN]={ 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba };
//用printf打印输出,模拟单片机发送单字符
void UART_Send_Byte(u8 ch)
{
printf("%02X ",ch);
}
int loop_send_uart(u8 *data,int delaycnt )
{
static int send_index = -1;
static int send_delayCnt =0;
send_index++;
if( send_index == 0 )
{
send_delayCnt = delaycnt;
}
else if( send_index >= MAX_SEND_LEN)
{
if(--send_delayCnt<=0)
{
send_index = -1;
send_delayCnt = delaycnt;
return 0xFF;//finish signal
}
else
return send_index;
}
UART_Send_Byte( data[send_index] );
return send_index;
}
int main(int argc, char **argv)
{
printf("=======C_BuildTime=[%s]==============\r\n\r\n",__TIME__ );
int cnt = 0;
int ret_index = 0;
while(1)
{
printf("A_count = %d ::", cnt++ );
printf("send_DATA=[");
ret_index = loop_send_uart(g_sendBuffer1,3);
printf("],ret_index=%02x.\n",ret_index );
msleep(500);
if(ret_index==0xFF) //发送完第1组数据
break;
}
while(1)
{
printf("B_count = %d ::", cnt++ );
printf("send_DATA=[");
ret_index = loop_send_uart(g_sendBuffer2,3);
printf("],ret_index=%02x.\n",ret_index );
msleep(500);
if(ret_index==0xFF) //发送完第2组数据
break;
}
return 0;
}
运行结果如下:
//定时发送每字节的数据:
/*
* for linux
#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<unistd.h>
*/
//for windows
#include <windows.h>
#include <stdio.h>
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned long
#define u64 unsigned long long
long g_sys_timestamp = 0;//系统时间戳,单位msec
long get_timestamp()
{
/*
struct timeval tv;
gettimeofday(&tv, NULL);
long sec = tv.tv_sec;
static u64 init_ms = 0;
u64 curr_ms = sec * 1000 + tv.tv_usec / 1000;
if (init_ms == 0)
{
init_ms = curr_ms;
}
return (long)(curr_ms - init_ms);*/
static u64 init_ms = 0;
if (init_ms == 0)
{
init_ms = GetTickCount();
}
return (GetTickCount()- init_ms);
}
void msleep(int ms)
{
//usleep(1000 * ms);
Sleep(ms);
}
//=============================================
#define MAX_SEND_LEN 10
u8 g_sendBuffer1[MAX_SEND_LEN] = { 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa };
u8 g_sendBuffer2[MAX_SEND_LEN] = { 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba };
//模拟单片机发送单字符
void UART_Send_Byte(u8 ch)
{
//TODO user code...
static long old_tick = 0;
printf("[%d]SEND=%02X.\n", g_sys_timestamp, ch);
printf("Curr=%d,old=%d.take=(%d)ms.\n", g_sys_timestamp, old_tick, g_sys_timestamp - old_tick);
old_tick = g_sys_timestamp;
}
// call_interval_set :每隔N ms调用1次串口发送
int timer_send_uart(u8* data, int delaycnt, const int call_interval_set)
{
static long old_tick = 0;
static int send_index = -1;
static int send_delayCnt = 0;
if (g_sys_timestamp < old_tick + call_interval_set)
{
return send_index;
}
old_tick = g_sys_timestamp;
//TODO timer process here:
send_index++;
if (send_index == 0)
{
send_delayCnt = delaycnt;
}
else if (send_index >= MAX_SEND_LEN)
{
if (--send_delayCnt <= 0)
{
send_index = -1;
send_delayCnt = delaycnt;
return 0xFF;//finish signal
}
else
return send_index;
}
UART_Send_Byte(data[send_index]);
return send_index;
}
//在循环中定时发送数据处理
int main(int argc, char** argv)
{
printf("=======C_BuildTime=[%s]==============\r\n\r\n", __TIME__);
int ret_index = 0;
while (1)
{
//假设这个变量是在中断每1ms自增的时间戳
//注意:long为4字节,时间最大值达到1193小时
g_sys_timestamp = get_timestamp();
ret_index = timer_send_uart(g_sendBuffer1, 5, 1000);//目的:做到每个数据定时发送
msleep(5 + rand() % 5); //随机延时,模拟用户逻辑的随机性
if (ret_index == 0xFF) //发送完第1组数据
break;
}
printf("\n[%d]=======Finish!======\n", g_sys_timestamp);
return 0;
}
定时运行效果如下: