普通单片机引脚模拟串口给上位机发送数据
1、【1】
模拟串口发送数据原理:
标准数据格式:起始位(1bit) + 数据位(8bit) + 校验位(无) + 停止位(1bit)
说明:
起始位为低电平。
停止位为高电平。
数据位先发低位,再发高位。
为了简便无校验位。
【2】
波特率的计算:
发送一帧数据共有10位(1 + 8 + 1)。
按照波特率为9600计算,即1秒传输9600位。
传输1位所用的时间为:
1/9600s = 0.00010417s = 0.10417ms = 104us
即传输1位所用的时间约为:104us。
定时器产生104us中断即可实现9600pbs波特率传输。

2、【1】
建立好相应的工程,并配置好编译、链接、输出选项。
【2】
编写系统上电函数,根据不同单片机需要配置不同的参数信息。
主要配置单片机内核时钟、关闭看门狗、引脚输入/输出/模式配置。
关闭低点检查、关闭所有中断、关闭比较器等等。
static void vSystem_PowerOn (void)
{
}

3、【1】
定时器初始化。
配置定时0,其时钟为1MHZ,即1us,重装载值为104,刚好104us。
使能定时器0,使能定时器0中断,使能全局中断。
定时器0中断溢出标志位置零。
定时器0为104us中断。
#define TIM0_COUNT (256 - 104)
static void vTimer_Init(void)
{
OPTION = 0B00000000;
TMR0 = TIM0_COUNT;
T0IF = 0;
GIE = 1;
T0IE = 1;
}
【2】
编写定时器0中断服务函数。
每104us中断一次。
重装初始为(256 - 104).
//Timer0 interrupt service
//104us interrupt
void interrupt ISR(void)
{
if(T0IE && T0IF)
{
T0IF = 0;
T0IE = 0;
TMR0 = TIM0_COUNT;
vGenerate_BaudRate();
T0IE = 1;
}
}


4、【1】
定义模拟串口发送数据引脚的高低电平。
#define AUART_PTXD_Pin PC3
#define AUART_PTXD_SET() AUART_PTXD_Pin = 1
#define AUART_PTXD_CLR() AUART_PTXD_Pin = 0
【2】
定义产生9600bps的波特率时基。
typedef struct
{
u16 BaudRate9600BPS;
}AnalogUartStruct_Type;
AnalogUartStruct_Type AnalogUartStruct;
void vGenerate_BaudRate(void)//104us time basic
{
if(AnalogUartStruct.BaudRate9600BPS)
AnalogUartStruct.BaudRate9600BPS--;
}
void vAnalogTimers(void)//104us = 9600pbs
{
AnalogUartStruct.BaudRate9600BPS = 1;
while(AnalogUartStruct.BaudRate9600BPS);
}
【3】
编写模拟串口发送一个字节函数。
每发送一个字节数据需要发送10位,一位为开始位,一位为停止位,总共10位。
先发送低位,再发送高位。
0Bit位开始位。
9Bit位停止位。
1Bit~8Bit位数据位,刚好一个字节。
static void vAnalogUart_Send_ByteDate(u8 byteDat)
{
u16 allDat = 0;
u8 i = 0;
allDat = byteDat;
allDat = (allDat << 1) | 0x0200;
for(i=0; i<10; i++)
{
if((allDat >> i) & 0x0001)
AUART_PTXD_SET();
else
AUART_PTXD_CLR();
vAnalogTimers();//104us
}
}
【4】
编写模拟串口发送数据函数。
可以一次性发送多个字节。
额外加上开始数据0x55和结束数据0xAA
void vAnalogUart_SendDate(u8 * byteDat, u8 len)
{
u8 i = 0;
vAnalogUart_Send_ByteDate(0x55);
for(i=0; i<len; i++)
vAnalogUart_Send_ByteDate(byteDat[i]);
vAnalogUart_Send_ByteDate(0xAA);
}



5、【1】
编写简单的延时函数。
在主函数中使用到此延时函数。
void DelayMs(unsigned char Time)
{
unsigned char a = 0, b = 0;
for(a=0; a<Time; a++)
{
for(b=0; b<252; b++);
}
}
【2】
编写主函数。
向上位机中一次性发送6字节数据,加上开始和结束数据0x55和0xAA,总共8字节数据。
void main(void)
{
u8 dat[6] = {0x8F, 0xAD, 0x52, 0x29, 0x0A, 0xBC};
vSystem_PowerOn();
vTimer_Init();
while(1)
{
vAnalogUart_SendDate(dat, 6);
DelayMs(250);
}
}


6、【1】
编译源码无误后,生成可执行文件,将可执行文件下载到单片机中,查看上位机输出数据情况。
【2】
若上位机中输出0x55, 0x8F, 0xAD, 0x52, 0x29, 0x0A, 0xBC, 0xAA,则说明模拟串口给上位机发送数据已成功。




