以下是GLM帮助修改的一个用串口助手窗口打印时间的程序,注意,因为串口助手是烧写之后延时1s才打开串口的,所以在main的while(1)之前printf内容看不到,而因为while(1)内各分支执行太快,所以又没法在while(1)中直接printf一句话。
所以GLM帮助下修改了printf程序为:
这样仅仅输出一次printf
- /******************************************************************************
- * @file main.c
- * @author 硬件家园 (优化版)
- * @version V2.0
- * @project STC8H单片机基础板
- *******************************************************************************/
-
- /* Includes ------------------------------------------------------------------*/
- #include <STC8H.H>
- #include <stdio.h>
-
- /* Private define-------------------------------------------------------------*/
- #define MAIN_Fosc 11059200L //定义主时钟 11059200L
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
-
- /* Private variables----------------------------------------------------------*/
- bit TX_Busy_Flag = 0; //串口发送忙碌标志位
-
- bit sec_update_flag = 0;
- bit led_toggle_flag = 0; // 新增:LED翻转标志位
-
- unsigned char ucSec=0;
- //unsigned char ucMin=0;
- //unsigned char ucHour=0;
- unsigned char ucStartupCount=0;
-
- /* Public variables-----------------------------------------------------------*/
- u8 xdata ledIndex;
- u8 code ledNum[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
-
- /* Private function prototypes------------------------------------------------*/
- void Timer0_Init(void);
- void UART1_Init(void);
- void update_time(void);
-
- void led_flash_toggle(){
- P6=~P6;
- }
- /*
- * @name main
- * @brief 主函数
- * @param None
- * @retval None
- */
- int main()
- {
- EA = 1; //打开总中断
- P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能
-
- P0M1 = 0x30; P0M0 = 0x30;
- P1M1 = 0x30; P1M0 = 0x30;
- P2M1 = 0x3c; P2M0 = 0x3c;
- P3M1 = 0x50; P3M0 = 0x50;
- P4M1 = 0x3c; P4M0 = 0x3c;
- P5M1 = 0x0c; P5M0 = 0x0c;
- P6M1 = 0x00; P6M0 = 0xff; //设置为推挽输出
- P7M1 = 0x00; P7M0 = 0x00;
-
- P40 = 0; //LED Power On
- ledIndex = 0;
-
- Timer0_Init();
- UART1_Init();
-
- //串口打印启动信息(只在开机打印一次)
- printf("Initialization completed, system startup!\r\n");
- P6=0XF0;
- while(1)
- {
- // 任务1:处理LED翻转 (非阻塞方式)
- if(led_toggle_flag == 1)
- {
- led_toggle_flag = 0;
- led_flash_toggle();
- }
-
- // 任务2:处理时间更新
- if(sec_update_flag == 1)
- {
- update_time();
- // %02bd 表示:2位宽度,不足补0,bd是C51针对unsigned char的格式符
- //printf("Time is %02bd:%02bd:%02bd\r\n", ucHour, ucMin, ucSec);
- // --- 核心改进:启动窗口打印逻辑 ---
- if(ucStartupCount < 3) // 前3秒:打印启动信息,给你留3秒时间开串口助手
- {
- printf("Initialization completed, system startup!\r\n");
- ucStartupCount++;
- }
- else // 3秒后:进入正常的时间打印
- {
- //printf("Time is %02bd:%02bd:%02bd\r\n", ucHour, ucMin, ucSec);
- }
- }
- }
- }
-
-
- void Timer0_Init(void) //20毫秒@11.0592MHz
- {
- AUXR &= 0x7F; //定时器时钟12T模式
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0x00; //设置定时初始值
- TH0 = 0xB8; //设置定时初始值
- TF0 = 0; //清除TF0标志
- ET0 = 1; //允许定时器0中断
- TR0 = 1; //定时器0开始计时
- }
-
- void Timer0_Isr() interrupt 1 //去掉了 using 3,更安全
- {
- static unsigned char cnt_20ms = 0;
- static unsigned char cnt_500ms = 0; // 新增:用于LED闪烁的计数器
-
- cnt_20ms++;
- cnt_500ms++;
-
- // 1秒计时逻辑
- if(cnt_20ms >= 50)
- {
- sec_update_flag = 1;
- cnt_20ms = 0;
- }
-
- // 500ms LED翻转逻辑 (原来的 2250ms * 2 = 4.5秒太慢了,这里改为1秒闪一次,可自行修改)
- if(cnt_500ms >= 25) // 25 * 20ms = 500ms
- {
- led_toggle_flag = 1;
- cnt_500ms = 0;
- }
- }
-
- void UART1_Init()//115200bps@11.0592MHz,
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //设定定时器1为16位自动重装方式
- TL1 = 0xFE; //设定定时初值
- TH1 = 0xFF; //设定定时初值
- ET1 = 0; //禁止定时器1中断
- TR1 = 1; //启动定时器1
-
- ES = 1;
- EA = 1;
- TI = 1;
- }
-
- void SendData(unsigned char dat)
- {
- while(TX_Busy_Flag); //等待前面的数据发送完
- TX_Busy_Flag = 1; //置位忙碌标志
- SBUF = dat; //写数据至UART1寄存器
- }
-
- extern char putchar(char c)
- {
- SendData((unsigned char)c);
- return c;
- }
-
- void UART1_isr() interrupt 4 // 去掉了 using 3
- {
- if(RI)
- {
- RI = 0; //清除接收中断标志
- //volatile unsigned char dummy = SBUF; //读取SBUF清除潜在状态(若不需接收可忽略)
- //(void)dummy; // 防止编译器警告
- }
-
- if(TI)
- {
- TI = 0; //清除发送中断标志
- TX_Busy_Flag = 0; //清忙碌标志
- }
- }
-
- void update_time(void)
- {
- sec_update_flag = 0;
- ucSec++;
- if(ucSec >= 60)
- {
- ucSec = 0;
- }
- }
-
- // 注意:delay_ms 函数已经不再需要,可以删除,如果其他地方用不到的话
复制代码
|