/*****************************************************************************************
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Filename: main.c
MCU: STC12C5608AD(28Pin)
Compiler: Keil uVision 5
Oscillator: 11.0592MHz
Designer: liht1634@163.com
Date: 2019-06-27
Version: V1.0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
说明:
1、初始化时P3.0 P3.1口不要将输出置为0,否则串口输出数据不对(为0);用12MHz输出到串口数据不对
2、包含stdio.h这个头文件
3、用printf函数前要先关闭串口中断,可以在调用函数之后打开中断,不然容易出现不能正常输出数值的情况
4、要先置TI=1;即TI标志位为高电平
例程:
ES=0;
TI=1;
printf("%s","SHT10");
ES=1;
可省略“TI=0” 在51的串口中用这个函数挺好用的,但是编译程序会增加不少的字节。
5、WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
在printf时有此警告,不用理会,输出正确
6、为什么中断处理函数中不能使用printf语句
一个ISR应该避免调用不可重入函数。一些标准库函数是不可重入的,如经常实现的malloc和printf。因为中断可能发生在执行任务中,
因为任务可能是在malloc的函数调用中,如果ISR调用此相同的不可重入函数,由此产生的行为可能是灾难性的。
不可重入函数是指这样的一类函数,不可以在它还没有返回就再次被调用。例如printf、malloc、free等都是不可重入函数。
因为信号可能在任何时候发生,例如在printf执行过程中,因此不能在信号处理函数里调用printf,否则printf将会被重入。
函数不可重入大多数是因为在函数中引用了全局变量。例如,printf会引用全局变量stdout、malloc、free会引用全局的内存分配表。
解决办法:可在中断函数做标志,判断是否进入过此中断(具体可参看190624_SmartSwitchController)
提醒:
本程序选择“接收缓冲区:文本模式”
*****************************************************************************************/
#include "STC5608AD.h"
#include "intrins.h" //_nop_()
#include "stdio.h" //用于printf
#include "stdarg.h" //用于vsprintf函数原型
#define T0H 0xFC //Timer0 = 1mS
#define T0L 0x66
/*------------------------------------------------
函数声明
------------------------------------------------*/
void SendStr(unsigned char *s);
void uart_printf(const char *fmt,...);
unsigned char Timer0Flag = 0;
/*------------------------------------------------
延时1000mS函数
------------------------------------------------*/
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*------------------------------------------------
串口初始化
------------------------------------------------*/
void InitUART (void)
{
SCON = 0x50; // SCON:模式1,8-bitUART,使能接收
TMOD |= 0x21; // TMOD: Timer1, mode2, 8-bit重装
TH1 = TL1 = 0xFD; // TH1重装值0xFD,9600波特率,晶振11.0592MHz
TR1 = 1; // TR1:Timer1打开
IE = 0xA2; // 关闭定时器1中断
EA = 1; // 打开总中断
// ES = 1; // 打开串口中断
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
int a = 0x99; //0x99 = 153D
InitUART();
/////////////////////////////////////////////////通过串口输出到电脑方法1
SendStr("InitStart \n");
uart_printf("10进制:%d \n",a); //发送一个指定类型数据
ES = 1; //打开串口中断
/////////////////////////////////////////////////
/////////////////////////////////////////////////通过串口输出到电脑方法2
ES = 0;
TI = 1;
printf("10进制:%d\n",a); //打印输出一个类型数据
ES = 1; //打开串口中断
/////////////////////////////////////////////////
Delay1000ms();
TL0 = T0L;
TH0 = T0H;
TR0 = 1; //启动Timer0
Delay1000ms();
AUXR = 0x10; // AD中断使能
IPH = 0x20;
IP = 0x2A; // ADC优先级3(最高),Timer0/Timer1优先级1,其它0
while(1)
{
// Delay1000ms();
// Delay1000ms();
SendStr("MainLoop \n");
Delay1000ms();
Delay1000ms();
if(Timer0Flag == 1)
{
Timer0Flag = 0;
SendStr("Timer1Start \n");
TR0 = 1;
}
}
}
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void SendByte(unsigned char c)
{
if(c == '\n') //如果遇到\n就换行
{
//发送CR(Carriage Return)
SBUF = 0x0D;
while(!TI); //等待发送完成
TI = 0;
//发送 LF(NL line feed,new line)
SBUF = 0x0A;
while(!TI); //等待发送完成
TI = 0;
}
else
{
SBUF = c;
while(!TI); //等待发送完成
TI = 0;
}
}
/*------------------------------------------------
发送一个字符串
------------------------------------------------*/
void SendStr(unsigned char *s)
{
while(*s != '\0')// \0 表示字符串结束标志,通过检测是否字符串末尾
{
SendByte(*s);
s++;
}
}
/*------------------------------------------------
发送一个指定类型数据
------------------------------------------------*/
void uart_printf(const char *fmt,...)
{
va_list ap;
char xdata string[1024]; //访问内部拓展RAM,非访问外部RAM,不能超过内部拓展RAM大小(此处为1024)
va_start(ap,fmt);
vsprintf(string,fmt,ap); //此处也可以使用sprintf函数,用法差不多,稍加修改即可
SendStr(string);
va_end(ap);
}
/*------------------------------------------------
Timer0中断程序
------------------------------------------------*/
void Timer0() interrupt 1
{
TL0 = T0L;
TH0 = T0H;
Timer0Flag = 1;
TR0 = 0;
}
/*------------------------------------------------
串口中断程序
------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char Temp; //定义临时变量
if(RI) //判断是接收中断产生
{
RI = 0; //标志位清零
Temp = SBUF; //读入缓冲区的值
SBUF = Temp; //把接收到的值再发回电脑端
}
if(TI) //如果是发送标志位,清零
TI=0;
}
/*****************************************************************************************
End
*****************************************************************************************/
评论10