开EAXFR:
小工具计算波特率:
不建议在声明时赋初值,最好改在函数内赋值,data的直接被清零了:
- #include "STC8G.h"
- #include "intrins.h"
-
- // 宏定义
- #define FOSC 11059200UL // 晶振频率(11.0592MHz)
- #define BAUD 9600 // 波特率
- #define WDT_TIMEOUT 0x07 // 看门狗超时时间(0x07对应最长超时,约18ms@11.0592MHz)
-
- // 全局变量:5秒计时计数器(定时器0每10ms中断一次,累计500次为5秒)
- unsigned int count_5s = 0;
- // 待发送的数据
- unsigned char xdata sendData[] = {0x3A, 0x16, 0xA0, 0x01, 0x01, 0xB8, 0x00, 0x0D, 0x0A};
- #define DATA_LEN sizeof(sendData)/sizeof(sendData[0])
-
- // 初始化看门狗
- void WDT_Init(void) {
- WDT_CONTR = WDT_TIMEOUT; // 设置超时时间
- WDT_CONTR |= 0x10; // 启动看门狗
- EA = 1; // 允许总中断(看门狗溢出会复位,无需中断使能)
- }
-
- // 喂狗函数(定时调用,防止看门狗复位)
- void WDT_Feed(void) {
- WDT_CONTR |= 0x08; // 重新装载看门狗计数器
- }
-
- // 初始化定时器0(用于10ms定时中断)
- void Timer0_Init(void) {
- TMOD &= 0xF0; // 清除定时器0配置
- TMOD |= 0x01; // 定时器0工作在方式1(16位定时)
- // 计算初值(10ms@11.0592MHz,12T模式)
- TH0 = (65536 - (FOSC / 12 / 100)) / 256; // 100Hz = 10ms
- TL0 = (65536 - (FOSC / 12 / 100)) % 256;
- ET0 = 1; // 允许定时器0中断
- TR0 = 1; // 启动定时器0
- EA = 1; // 允许总中断
- }
-
- // 定时器0中断服务函数(每10ms触发一次)
- void Timer0_ISR(void) interrupt 1 {
- // 重新装载初值
- TH0 = (65536 - (FOSC / 12 / 100)) / 256;
- TL0 = (65536 - (FOSC / 12 / 100)) % 256;
-
- count_5s++; // 每10ms计数+1
- if (count_5s >= 500) { // 500*10ms = 5000ms = 5秒
- count_5s = 0; // 重置计数器
- }
-
- WDT_Feed(); // 每10ms喂一次狗(远小于看门狗超时时间)
- }
-
- // 初始化串口
- void UART_Init(void) {
- // 配置TXD引脚(P3.1)为推挽输出
- P3M0 = 0x02; // P3.1推挽输出
- P3M1 = 0x00;
-
- // 配置波特率(定时器1方式2)
- // TMOD &= 0x0F;
- // TMOD |= 0x20; // 定时器1方式2(8位自动重装载)
- // TH1 = (unsigned char)(256 - (FOSC / (BAUD * 12 * 16)));
- // TL1 = TH1;
- // TR1 = 1; // 启动定时器1
-
- // SCON = 0x50; // 串口方式1(8位数据)
- // ES = 0; // 关闭串口中断(仅发送)
-
- PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器时钟1T模式
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //设置定时器模式
- TMOD |= 0x20; //设置定时器模式
- TL1 = 0xDC; //设置定时初始值
- TH1 = 0xDC; //设置定时重载值
- ET1 = 0; //禁止定时器中断
- TR1 = 1; //定时器1开始计时
-
- // SCON = 0x50; //8位数据,可变波特率
- // AUXR |= 0x40; //定时器时钟1T模式
- // AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- // TMOD &= 0x0F; //设置定时器模式
- // TL1 = 0xE0; //设置定时初始值
- // TH1 = 0xFE; //设置定时初始值
- // ET1 = 0; //禁止定时器中断
- // TR1 = 1; //定时器1开始计时
- }
-
- // 串口发送单个字节
- void UART_SendByte(unsigned char dat) {
- SBUF = dat;
- while (!TI); // 等待发送完成
- TI = 0; // 清除标志位
- }
-
- // 发送数据数组
- void UART_SendArray(unsigned char *arr, unsigned char len) {
- unsigned char i;
- for (i = 0; i < len; i++) {
- UART_SendByte(arr[i]);
- }
- }
-
- void main(void) {
- P_SW2=0x80;
- P0M0 = 0x00; P0M1 = 0x00;
- P1M0 = 0x00; P1M1 = 0x00;
- P2M0 = 0x00; P2M1 = 0x00;
- P3M0 = 0x00; P3M1 = 0x00;
- P4M0 = 0x00; P4M1 = 0x00;
- P5M0 = 0x00; P5M1 = 0x00;
- P6M0 = 0x00; P6M1 = 0x00;
- P7M0 = 0x00; P7M1 = 0x00;
-
- UART_Init(); // 初始化串口
- Timer0_Init(); // 初始化定时器0(10ms中断)
- WDT_Init(); // 初始化并启动看门狗
-
- while (1) {
- if (count_5s == 0) { // 每5秒触发一次发送
- UART_SendArray(sendData, DATA_LEN);
- // 发送完成后等待计数器重新计数,避免重复发送
- while (count_5s == 0);
- }
- }
- }
复制代码
|