STC单片机实现printf

STC15单片机-串口打印printf重定向 某些库函数的运行速度也比较慢,例如,memcpy()。microlib 是缺省 C 库的备选库,它指在需要装入到极少量内存中的深层嵌入式应用程序配合使用,这些应用程序不在操作系统中运行。网上文章许多都是说改写fputc函数,但我在这个程序中试了是不行的,会编译出错,定位到函数的FILE类型上,的时候,可以在keil软件的设置里,勾选Use MicroLIB选项,就可以使用fputc函数来实现重定向了。如果Cnt的类型是uint8_t的话,下面的格式化不变,还是%u,则串口输出的不是加1,而是加256了。 阅读详情
AI摘要

本文介绍如何在STC8Axx单片机中使用printf函数发送串口数据,并结合外部中断实现特定事件(如按键按下)时的串口打印。首先展示了初始化串口的代码,然后演示了如何在外部中断INT0下降沿触发时,通过printf打印中断计数。在中断服务函数中,LED状态也会随着中断次数翻转,实现了中断和串口通信的结合。

 

《一》直接使用系统自带的printf函数:特别注意需要置位TI=1,否则是无法发送的,程序如下:

#include "STC8Axx.h"
#include <stdio.h>
#include <intrins.h>
void UartInit( void )           /* 115200bps@11.0592MHz */
{
	SCON	= 0x50;         /* 8位数据,可变波特率 */
	AUXR	|= 0x40;        /* 定时器1时钟为Fosc,即1T */
	AUXR	&= 0xFE;        /* 串口1选择定时器1为波特率发生器 */
	TMOD	&= 0x0F;        /* 设定定时器1为16位自动重装方式 */
	TL1	= 0xE8;         /* 设定定时初值 */
	TH1	= 0xFF;         /* 设定定时初值 */
	ET1	= 0;            /* 禁止定时器1中断 */
	TR1	= 1;            /* 启动定时器1 */
	ES	= 1;            /* 使能串口1中断 */
	TI	= 1;
}


void Delay100ms()               /* @11.0592MHz */
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i	= 5;
	j	= 52;
	k	= 195;
	do
	{
		do
		{
			while ( --k )
				;
		}
		while ( --j );
	}
	while ( --i );
}


unsigned int cnt = 0;
void main()
{
	UartInit();
	EA = 1;
	printf( "printf Test!\r\n" );
	while ( 1 )
	{
		Delay100ms();
		Delay100ms();
		Delay100ms();
		printf( "BAUD = %d \r\n", (int) cnt );
		cnt++;
	}
}

 STC8Axx.h

#ifndef __STC8F_H_
#define __STC8F_H_

/////////////////////////////////////////////////

//包含本头文件后,不用另外再包含"REG51.H"


//内核特殊功能寄存器
sfr ACC         =   0xe0;
sfr B           =   0xf0;
sfr PSW         =   0xd0;
sbit CY         =   PSW^7;
sbit AC         =   PSW^6;
sbit F0         =   PSW^5;
sbit RS1        =   PSW^4;
sbit RS0        =   PSW^3;
sbit OV         =   PSW^2;
sbit P          =   PSW^0;
sfr SP          =   0x81;
sfr DPL         =   0x82;
sfr DPH         =   0x83;
sfr TA          =   0xae;
sfr DPS         =   0xe3;
sfr DPL1        =   0xe4;
sfr DPH1        =   0xe5;


//I/O 口特殊功能寄存器
sfr P0          =   0x80;
sfr P1          =   0x90;
sfr P2          =   0xa0;
sfr P3          =   0xb0;
sfr P4          =   0xc0;
sfr P5          =   0xc8;
sfr P6          =   0xe8;
sfr P7          =   0xf8;
sfr P0M0        =   0x94;
sfr P0M1        =   0x93;
sfr P1M0        =   0x92;
sfr P1M1        =   0x91;
sfr P2M0        =   0x96;
sfr P2M1        =   0x95;
sfr P3M0        =   0xb2;
sfr P3M1        =   0xb1;
sfr P4M0        =   0xb4;
sfr P4M1        =   0xb3;
sfr P5M0        =   0xca;
sfr P5M1        =   0xc9;
sfr P6M0        =   0xcc;
sfr P6M1        =   0xcb;
sfr P7M0        =   0xe2;
sfr P7M1        =   0xe1;

sbit P00        =   P0^0;
sbit P01        =   P0^1;
sbit P02        =   P0^2;
sbit P03        =   P0^3;
sbit P04        =   P0^4;
sbit P05        =   P0^5;
sbit P06        =   P0^6;
sbit P07        =   P0^7;
sbit P10        =   P1^0;
sbit P11        =   P1^1;
sbit P12        =   P1^2;
sbit P13        =   P1^3;
sbit P14        =   P1^4;
sbit P15        =   P1^5;
sbit P16        =   P1^6;
sbit P17        =   P1^7;
sbit P20        =   P2^0;
sbit P21        =   P2^1;
sbit P22        =   P2^2;
sbit P23        =   P2^3;
sbit P24        =   P2^4;
sbit P25        =   P2^5;
sbit P26        =   P2^6;
sbit P27        =   P2^7;
sbit P30        =   P3^0;
sbit P31        =   P3^1;
sbit P32        =   P3^2;
sbit P33        =   P3^3;
sbit P34        =   P3^4;
sbit P35        =   P3^5;
sbit P36        =   P3^6;
sbit P37        =   P3^7;
sbit P40        =   P4^0;
sbit P41        =   P4^1;
sbit P42        =   P4^2;
sbit P43        =   P4^3;
sbit P44        =   P4^4;
sbit P45        =   P4^5;
sbit P46        =   P4^6;
sbit P47        =   P4^7;
sbit P50        =   P5^0;
sbit P51        =   P5^1;
sbit P52        =   P5^2;
sbit P53        =   P5^3;
sbit P54        =   P5^4;
sbit P55        =   P5^5;
sbit P56        =   P5^6;
sbit P57        =   P5^7;
sbit P60        =   P6^0;
sbit P61        =   P6^1;
sbit P62        =   P6^2;
sbit P63        =   P6^3;
sbit P64        =   P6^4;
sbit P65        =   P6^5;
sbit P66        =   P6^6;
sbit P67        =   P6^7;
sbit P70        =   P7^0;
sbit P71        =   P7^1;
sbit P72        =   P7^2;
sbit P73        =   P7^3;
sbit P74        =   P7^4;
sbit P75        =   P7^5;
sbit P76        =   P7^6;
sbit P77        =   P7^7;

//如下特殊功能寄存器位于扩展RAM区域
//访问这些寄存器,需先将P_SW2的BIT7设置为1,才可正常读写
#define P0PU        (*(unsigned char volatile xdata *)0xfe10)
#define P1PU        (*(unsigned char volatile xdata *)0xfe11)
#define P2PU        (*(unsigned char volatile xdata *)0xfe12)
#define P3PU        (*(unsigned char volatile xdata *)0xfe13)
#define P4PU        (*(unsigned char volatile xdata *)0xfe14)
#define P5PU        (*(unsigned char volatile xdata *)0xfe15)
#define P6PU        (*(unsigned char volatile xdata *)0xfe16)
#define P7PU        (*(unsigned char volatile xdata *)0xfe17)
#define P0NCS       (*(unsigned char volatile xdata *)0xfe18)
#define P1NCS       (*(unsigned char volatile xdata *)0xfe19)
#define P2NCS       (*(unsigned char volatile xdata *)0xfe1a)
#define P3NCS       (*(unsigned char volatile xdata *)0xfe1b)
#define P4NCS       (*(unsigned char volatile xdata *)0xfe1c)
#define P5NCS       (*(unsigned char volatile xdata *)0xfe1d)
#define P6NCS       (*(unsigned char volatile xdata *)0xfe1e)
#define P7NCS       (*(unsigned char volatile xdata *)0xfe1f)

//系统管理特殊功能寄存器
sfr PCON        =   0x87;
#define SMOD        0x80
#define SMOD0       0x40
#define LVDF        0x20
#define POF         0x10
#define GF1         0x08
#define GF0         0x04
#define PD          0x02
#define IDL         0x01
sfr AUXR        =   0x8e;
#define T0x12       0x80
#define T1x12       0x40
#define UART_M0x6   0x20
#define T2R         0x10
#define T2_CT       0x08
#define T2x12       0x04
#define EXTRAM      0x02
#define S1ST2       0x01
sfr AUXR2       =   0x97;
#define TXLNRX      0x10
sfr BUS_SPEED   =   0xa1;
sfr P_SW1       =   0xa2;
sfr P_SW2       =   0xba;
#define EAXFR       0x80
sfr VOCTRL      =   0xbb;
sfr RSTCFG      =   0xff;

//如下特殊功能寄存器位于扩展RAM区域
//访问这些寄存器,需先将P_SW2的BIT7设置为1,才可正常读写
#define CKSEL       (*(unsigned char volatile xdata *)0xfe00)
#define CLKDIV      (*(unsigned char volatile xdata *)0xfe01)
#define IRC24MCR    (*(unsigned char volatile xdata *)0xfe02)
#define XOSCCR      (*(unsigned char volatile xdata *)0xfe03)
#define IRC32KCR    (*(unsigned char volatile xdata *)0xfe04)

//中断特殊功能寄存器
sfr IE          =   0xa8;
sbit EA         =   IE^7;
sbit ELVD       =   IE^6;
sbit EADC       =   IE^5;
sbit ES         =   IE^4;
sbit ET1        =   IE^3;
sbit EX1        =   IE^2;
sbit ET0        =   IE^1;
sbit EX0        =   IE^0;
sfr IE2         =   0xaf;
#define ET4         0x40
#define ET3         0x20
#define ES4         0x10
#define ES3         0x08
#define ET2         0x04
#define ESPI        0x02
#define ES2         0x01
sfr IP          =   0xb8;
sbit PPCA       =   IP^7;
sbit PLVD       =   IP^6;
sbit PADC       =   IP^5;
sbit PS         =   IP^4;
sbit PT1        =   IP^3;
sbit PX1        =   IP^2;
sbit PT0        =   IP^1;
sbit PX0        =   IP^0;
sfr IP2         =   0xb5;
#define PI2C        0x40
#define PCMP        0x20
#define PX4         0x10
#define PPWMFD      0x08
#define PPWM        0x04
#define PSPI        0x02
#define PS2         0x01
sfr IPH         =   0xb7;
#define PPCAH       0x80
#define PLVDH       0x40
#define PADCH       0x20
#define PSH         0x10
#define PT1H        0x08
#define PX1H        0x04
#define PT0H        0x02
#define PX0H        0x01
sfr IP2H        =   0xb6;
#define PI2CH       0x40
#define PCMPH       0x20
#define PX4H        0x10
#define PPWMFDH     0x08
#define PPWMH       0x04
#define PSPIH       0x02
#define PS2H        0x01
sfr INTCLKO     =   0x8f;
#define EX4         0x40
#define EX3         0x20
#define EX2         0x10
#define T2CLKO      0x04
#define T1CLKO      0x02
#define T0CLKO      0x01
sfr AUXINTIF    =   0xef;
#define INT4IF      0x40
#define INT3IF      0x20
#define INT2IF      0x10
#define T4IF        0x04
#define T3IF        0x02
#define T2IF        0x01

//定时器特殊功能寄存器
sfr TCON        =   0x88;
sbit TF1        =   TCON^7;
sbit TR1        =   TCON^6;
sbit TF0        =   TCON^5;
sbit TR0        =   TCON^4;
sbit IE1        =   TCON^3;
sbit IT1        =   TCON^2;
sbit IE0        =   TCON^1;
sbit IT0        =   TCON^0;
sfr TMOD        =   0x89;
#define T1_GATE     0x80
#define T1_CT       0x40
#define T1_M1       0x20
#define T1_M0       0x10
#define T0_GATE     0x08
#define T0_CT       0x04
#define T0_M1       0x02
#define T0_M0       0x01
sfr TL0         =   0x8a;
sfr TL1         =   0x8b;
sfr TH0         =   0x8c;
sfr TH1         =   0x8d;
sfr T4T3M       =   0xd1;
#define T4R         0x80
#define T4_CT       0x40
#define T4x12       0x20
#define T4CLKO      0x10
#define T3R         0x08
#define T3_CT       0x04
#define T3x12       0x02
#define T3CLKO      0x01
sfr T4H         =   0xd2;
sfr T4L         =   0xd3;
sfr T3H         =   0xd4;
sfr T3L         =   0xd5;
sfr T2H         =   0xd6;
sfr T2L         =   0xd7;
sfr TH4         =   0xd2;
sfr TL4         =   0xd3;
sfr TH3         =   0xd4;
sfr TL3         =   0xd5;
sfr TH2         =   0xd6;
sfr TL2         =   0xd7;
sfr WKTCL       =   0xaa;
sfr WKTCH       =   0xab;
#define WKTEN       0x80
sfr WDT_CONTR   =   0xc1;
#define WDT_FLAG    0x80
#define EN_WDT      0x20
#define CLR_WDT     0x10
#define IDL_WDT     0x08

//串行口特殊功能寄存器
sfr SCON        =   0x98;
sbit SM0        =   SCON^7;
sbit SM1        =   SCON^6;
sbit SM2        =   SCON^5;
sbit REN        =   SCON^4;
sbit TB8        =   SCON^3;
sbit RB8        =   SCON^2;
sbit TI         =   SCON^1;
sbit RI         =   SCON^0;
sfr SBUF        =   0x99;
sfr S2CON       =   0x9a;
#define S2SM0       0x80
#define S2ST4       0x40
#define S2SM2       0x20
#define S2REN       0x10
#define S2TB8       0x08
#define S2RB8       0x04
#define S2TI        0x02
#define S2RI        0x01
sfr S2BUF       =   0x9b;
sfr S3CON       =   0xac;
#define S3SM0       0x80
#define S3ST4       0x40
#define S3SM2       0x20
#define S3REN       0x10
#define S3TB8       0x08
#define S3RB8       0x04
#define S3TI        0x02
#define S3RI        0x01
sfr S3BUF       =   0xad;
sfr S4CON       =   0x84;
#define S4SM0       0x80
#define S4ST4       0x40
#define S4SM2       0x20
#define S4REN       0x10
#define S4TB8       0x08
#define S4RB8       0x04
#define S4TI        0x02
#define S4RI        0x01
sfr S4BUF       =   0x85;
sfr SADDR       =   0xa9;
sfr SADEN       =   0xb9;

//ADC 特殊功能寄存器
sfr ADC_CONTR   =   0xbc;
#define ADC_POWER   0x80
#define ADC_START   0x40
#define ADC_FLAG    0x20
sfr ADC_RES     =   0xbd;
sfr ADC_RESL    =   0xbe;
sfr ADCCFG      =   0xde;
#define ADC_RESFMT  0x20

//SPI 特殊功能寄存器
sfr SPSTAT      =   0xcd;
#define SPIF        0x80
#define WCOL        0x40
sfr SPCTL       =   0xce;
#define SSIG        0x80
#define SPEN        0x40
#define DORD        0x20
#define MSTR        0x10
#define CPOL        0x08
#define CPHA        0x04
sfr SPDAT       =   0xcf;

//IAP/ISP 特殊功能寄存器
sfr IAP_DATA    =   0xc2;
sfr IAP_ADDRH   =   0xc3;
sfr IAP_ADDRL   =   0xc4;
sfr IAP_CMD     =   0xc5;
#define IAP_IDL     0x00
#define IAP_READ    0x01
#define IAP_WRITE   0x02
#define IAP_ERASE   0x03
sfr IAP_TRIG    =   0xc6;
sfr IAP_CONTR   =   0xc7;
#define IAPEN       0x80
#define SWBS        0x40
#define SWRST       0x20
#define CMD_FAIL    0x10
sfr ISP_DATA    =   0xc2;
sfr ISP_ADDRH   =   0xc3;
sfr ISP_ADDRL   =   0xc4;
sfr ISP_CMD     =   0xc5;
sfr ISP_TRIG    =   0xc6;
sfr ISP_CONTR   =   0xc7;

//比较器特殊功能寄存器
sfr CMPCR1      =   0xe6;
#define CMPEN       0x80
#define CMPIF       0x40
#define PIE         0x20
#define NIE         0x10
#define PIS         0x08
#define NIS         0x04
#define CMPOE       0x02
#define CMPRES      0x01
sfr CMPCR2      =   0xe7;
#define INVCMPO     0x80
#define DISFLT      0x40

//PCA/PWM 特殊功能寄存器
sfr CCON        =   0xd8;
sbit CF         =   CCON^7;
sbit CR         =   CCON^6;
sbit CCF3       =   CCON^3;
sbit CCF2       =   CCON^2;
sbit CCF1       =   CCON^1;
sbit CCF0       =   CCON^0;
sfr CMOD        =   0xd9;
#define CIDL        0x80
#define ECF         0x01
sfr CL          =   0xe9;
sfr CH          =   0xf9;
sfr CCAPM0      =   0xda;
#define ECOM0       0x40
#define CCAPP0      0x20
#define CCAPN0      0x10
#define MAT0        0x08
#define TOG0        0x04
#define PWM0        0x02
#define ECCF0       0x01
sfr CCAPM1      =   0xdb;
#define ECOM1       0x40
#define CCAPP1      0x20
#define CCAPN1      0x10
#define MAT1        0x08
#define TOG1        0x04
#define PWM1        0x02
#define ECCF1       0x01
sfr CCAPM2      =   0xdc;
#define ECOM2       0x40
#define CCAPP2      0x20
#define CCAPN2      0x10
#define MAT2        0x08
#define TOG2        0x04
#define PWM2        0x02
#define ECCF2       0x01
sfr CCAPM3      =   0xdd;
#define ECOM3       0x40
#define CCAPP3      0x20
#define CCAPN3      0x10
#define MAT3        0x08
#define TOG3        0x04
#define PWM3        0x02
#define ECCF3       0x01
sfr CCAP0L      =   0xea;
sfr CCAP1L      =   0xeb;
sfr CCAP2L      =   0xec;
sfr CCAP3L      =   0xed;
sfr CCAP0H      =   0xfa;
sfr CCAP1H      =   0xfb;
sfr CCAP2H      =   0xfc;
sfr CCAP3H      =   0xfd;
sfr PCA_PWM0    =   0xf2;
sfr PCA_PWM1    =   0xf3;
sfr PCA_PWM2    =   0xf4;
sfr PCA_PWM3    =   0xf5;

//增强型PWM波形发生器特殊功能寄存器
sfr PWMCFG      =   0xf1;
#define CBIF        0x80
#define ETADC       0x40
sfr PWMIF       =   0xf6;
#define C7IF        0x80
#define C6IF        0x40
#define C5IF        0x20
#define C4IF        0x10
#define C3IF        0x08
#define C2IF        0x04
#define C1IF        0x02
#define C0IF        0x01
sfr PWMFDCR     =   0xf7;
#define INVCMP      0x80
#define INVIO       0x40
#define ENFD        0x20
#define FLTFLIO     0x10
#define EFDI        0x08
#define FDCMP       0x04
#define FDIO        0x02
#define FDIF        0x01
sfr PWMCR       =   0xfe;
#define ENPWM       0x80
#define ECBI        0x40

//如下特殊功能寄存器位于扩展RAM区域
//访问这些寄存器,需先将P_SW2的BIT7设置为1,才可正常读写
#define PWMC        (*(unsigned int  volatile xdata *)0xfff0)
#define PWMCH       (*(unsigned char volatile xdata *)0xfff0)
#define PWMCL       (*(unsigned char volatile xdata *)0xfff1)
#define PWMCKS      (*(unsigned char volatile xdata *)0xfff2)
#define TADCP       (*(unsigned char volatile xdata *)0xfff3)
#define TADCPH      (*(unsigned char volatile xdata *)0xfff3)
#define TADCPL      (*(unsigned char volatile xdata *)0xfff4)
#define PWM0T1      (*(unsigned int  volatile xdata *)0xff00)
#define PWM0T1H     (*(unsigned char volatile xdata *)0xff00)
#define PWM0T1L     (*(unsigned char volatile xdata *)0xff01)
#define PWM0T2      (*(unsigned int  volatile xdata *)0xff02)
#define PWM0T2H     (*(unsigned char volatile xdata *)0xff02)
#define PWM0T2L     (*(unsigned char volatile xdata *)0xff03)
#define PWM0CR      (*(unsigned char volatile xdata *)0xff04)
#define PWM0HLD     (*(unsigned char volatile xdata *)0xff05)
#define PWM1T1      (*(unsigned int  volatile xdata *)0xff10)
#define PWM1T1H     (*(unsigned char volatile xdata *)0xff10)
#define PWM1T1L     (*(unsigned char volatile xdata *)0xff11)
#define PWM1T2      (*(unsigned int  volatile xdata *)0xff12)
#define PWM1T2H     (*(unsigned char volatile xdata *)0xff12)
#define PWM1T2L     (*(unsigned char volatile xdata *)0xff13)
#define PWM1CR      (*(unsigned char volatile xdata *)0xff14)
#define PWM1HLD     (*(unsigned char volatile xdata *)0xff15)
#define PWM2T1      (*(unsigned int  volatile xdata *)0xff20)
#define PWM2T1H     (*(unsigned char volatile xdata *)0xff20)
#define PWM2T1L     (*(unsigned char volatile xdata *)0xff21)
#define PWM2T2      (*(unsigned int  volatile xdata *)0xff22)
#define PWM2T2H     (*(unsigned char volatile xdata *)0xff22)
#define PWM2T2L     (*(unsigned char volatile xdata *)0xff23)
#define PWM2CR      (*(unsigned char volatile xdata *)0xff24)
#define PWM2HLD     (*(unsigned char volatile xdata *)0xff25)
#define PWM3T1      (*(unsigned int  volatile xdata *)0xff30)
#define PWM3T1H     (*(unsigned char volatile xdata *)0xff30)
#define PWM3T1L     (*(unsigned char volatile xdata *)0xff31)
#define PWM3T2      (*(unsigned int  volatile xdata *)0xff32)
#define PWM3T2H     (*(unsigned char volatile xdata *)0xff32)
#define PWM3T2L     (*(unsigned char volatile xdata *)0xff33)
#define PWM3CR      (*(unsigned char volatile xdata *)0xff34)
#define PWM3HLD     (*(unsigned char volatile xdata *)0xff35)
#define PWM4T1      (*(unsigned int  volatile xdata *)0xff40)
#define PWM4T1H     (*(unsigned char volatile xdata *)0xff40)
#define PWM4T1L     (*(unsigned char volatile xdata *)0xff41)
#define PWM4T2      (*(unsigned int  volatile xdata *)0xff42)
#define PWM4T2H     (*(unsigned char volatile xdata *)0xff42)
#define PWM4T2L     (*(unsigned char volatile xdata *)0xff43)
#define PWM4CR      (*(unsigned char volatile xdata *)0xff44)
#define PWM4HLD     (*(unsigned char volatile xdata *)0xff45)
#define PWM5T1      (*(unsigned int  volatile xdata *)0xff50)
#define PWM5T1H     (*(unsigned char volatile xdata *)0xff50)
#define PWM5T1L     (*(unsigned char volatile xdata *)0xff51)
#define PWM5T2      (*(unsigned int  volatile xdata *)0xff52)
#define PWM5T2H     (*(unsigned char volatile xdata *)0xff52)
#define PWM5T2L     (*(unsigned char volatile xdata *)0xff53)
#define PWM5CR      (*(unsigned char volatile xdata *)0xff54)
#define PWM5HLD     (*(unsigned char volatile xdata *)0xff55)
#define PWM6T1      (*(unsigned int  volatile xdata *)0xff60)
#define PWM6T1H     (*(unsigned char volatile xdata *)0xff60)
#define PWM6T1L     (*(unsigned char volatile xdata *)0xff61)
#define PWM6T2      (*(unsigned int  volatile xdata *)0xff62)
#define PWM6T2H     (*(unsigned char volatile xdata *)0xff62)
#define PWM6T2L     (*(unsigned char volatile xdata *)0xff63)
#define PWM6CR      (*(unsigned char volatile xdata *)0xff64)
#define PWM6HLD     (*(unsigned char volatile xdata *)0xff65)
#define PWM7T1      (*(unsigned int  volatile xdata *)0xff70)
#define PWM7T1H     (*(unsigned char volatile xdata *)0xff70)
#define PWM7T1L     (*(unsigned char volatile xdata *)0xff71)
#define PWM7T2      (*(unsigned int  volatile xdata *)0xff72)
#define PWM7T2H     (*(unsigned char volatile xdata *)0xff72)
#define PWM7T2L     (*(unsigned char volatile xdata *)0xff73)
#define PWM7CR      (*(unsigned char volatile xdata *)0xff74)
#define PWM7HLD     (*(unsigned char volatile xdata *)0xff75)

//I2C特殊功能寄存器
//如下特殊功能寄存器位于扩展RAM区域
//访问这些寄存器,需先将P_SW2的BIT7设置为1,才可正常读写
#define I2CCFG      (*(unsigned char volatile xdata *)0xfe80)
#define ENI2C       0x80
#define MSSL        0x40
#define I2CMSCR     (*(unsigned char volatile xdata *)0xfe81)
#define EMSI        0x80
#define I2CMSST     (*(unsigned char volatile xdata *)0xfe82)
#define MSBUSY      0x80
#define MSIF        0x40
#define MSACKI      0x02
#define MSACKO      0x01
#define I2CSLCR     (*(unsigned char volatile xdata *)0xfe83)
#define ESTAI       0x40
#define ERXI        0x20
#define ETXI        0x10
#define ESTOI       0x08
#define SLRST       0x01
#define I2CSLST     (*(unsigned char volatile xdata *)0xfe84)
#define SLBUSY      0x80
#define STAIF       0x40
#define RXIF        0x20
#define TXIF        0x10
#define STOIF       0x08
#define TXING       0x04
#define SLACKI      0x02
#define SLACKO      0x01
#define I2CSLADR    (*(unsigned char volatile xdata *)0xfe85)
#define I2CTXD      (*(unsigned char volatile xdata *)0xfe86)
#define I2CRXD      (*(unsigned char volatile xdata *)0xfe87)

/////////////////////////////////////////////////

#endif

然而你想结合外部中断同时使用上述printf语句,是不能达到预期的效果。具体来说,用消抖按键连接P3.2即INT0,希望每次按键按下时串口打印“INT0 counter=   ”.

上述语句是不能响应外部中断的。经查是不应该启用TI=0;语句,同时添加串口发送字节语句,完整代码如下:

#include "STC8Axx.h"
#include <stdio.h>
#include <intrins.h>
void UartInit( void )           /* 115200bps@11.0592MHz */
{
	SCON	= 0x50;         /* 8位数据,可变波特率 */
	AUXR	|= 0x40;        /* 定时器1时钟为Fosc,即1T */
	AUXR	&= 0xFE;        /* 串口1选择定时器1为波特率发生器 */
	TMOD	&= 0x0F;        /* 设定定时器1为16位自动重装方式 */
	TL1	= 0xE8;         /* 设定定时初值 */
	TH1	= 0xFF;         /* 设定定时初值 */
	ET1	= 0;            /* 禁止定时器1中断 */
	TR1	= 1;            /* 启动定时器1 */
	ES	= 1;            /* 使能串口1中断 */
	/*	TI=1; */
}


void UART_SendChar( unsigned char Dat )
{
	SBUF = Dat;
	while ( !TI )
		;
	TI = 0;
}


char putchar( char c )
{
	UART_SendChar( c );
	return(c);
}


void Delay100ms()         /* @11.0592MHz */
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i	= 5;
	j	= 52;
	k	= 195;
	do
	{
		do
		{
			while ( --k )
				;
		}
		while ( --j );
	}
	while ( --i );
}


unsigned int	cnt	= 0;
unsigned int	INTcnt	= 0;
unsigned char	FLAG	= 0;
sbit		LED	= P2 ^ 1;
void main()
{
	UartInit();
	IT0	= 1;    /* 使能INT0下降沿中断 */
	EX0	= 1;    /* 使能INT0中断 */
	EA	= 1;

	printf( "STC8 UART1 Printf Test!\r\n" );
	while ( 1 )
	{
		Delay100ms();
		Delay100ms();
		Delay100ms();
		printf( "BAUD = %d \r\n", (int) cnt );
		cnt++;
		if ( FLAG == 1 )
		{
			INTcnt++;
			printf( "INT0 counts=%d\r\n", (int) INTcnt );
			FLAG = 0;
		}
	}
}


void INT0_Isr() interrupt 0
{
	FLAG	= 1;
	LED	= !LED;
}


STC15单片机-串口打印 主要是定义波特率的枚举类型,之前用串口都是程序写死波特率,要改的话又要用软件生成一次,这次的灵活点,定义该波特率枚举类型后在后面可以用switch语句列出这四种波特率的TH1、TL1的初始值,在使用时,直接修改波特率的变量的值即可,非常方便。与串口相关的分别是4个函数,串口初始化,串口发送字符,串口发送数组,串口发送字符串,另外对putchar函数进行重写,实现printf函数的重定向,为什么这里修改putchar函数而不是fputc函数,可以看之前的的文章(如果将形参赋给另一个指针,那指针就可++ 阅读详情

相关推荐

告别调试器:用STC8的printf函数打造你的“串口日志系统”

本文详细介绍了如何利用STC8单片机的printf函数构建高效的串口日志系统,替代传统调试器。通过硬件串口模块初始化、增强型日志框架设计及内存优化策略,实现轻量级且功能丰富的日志输出,适用于物联网设备和工业控制器等场景。

weixin_28678831的博客 387

51单片机STC8G使用printf函数的方法

原来是因为Keil C51的printf函数与标准C语言的printf函数不同,可在keil的菜单“Help-μVision Help”的帮助文件中查看关于printf函数的介绍,在使用C51的printf函数打印%d/i/u/o/x/X格式时的数值时,需要指定该变量的存储格式l/L/b/B。测试程序,主频为为22.1184MHz,串口1配置为9600bps,打印“Hello World!可看出输出的并不是我们想要的数值0,1,2…,而是放大了256倍,②16位数据,格式为%hd;,其他型号请自行测试;

wanglong3713的博客。 3729

别再手动发数据了!手把手教你用Keil C51的printf函数调试STC单片机串口

本文详细介绍了如何在Keil C51环境下使用printf函数高效调试STC单片机串口输出。通过硬件配置、putchar函数重定义及高级应用技巧,大幅提升调试效率,特别适合嵌入式开发中的变量监控和状态报告。

weixin_30372371的博客 454

STC单片机使用Printf

#include "STC8Axx.h" #include "Uart1.h" #include "Sys.h" #include <intrins.h> #include <stdio.h> //用于printf #include <stdarg.h> //用于vsprintf函数原型 bit bUart1Busy; bit bUart1ReceiveFinish = 0; //串口1接收完成标志 (1: 表.

清幽竹的博客 2692

从串口助手看数据:手把手教你用Keil C51的printf高效调试STC单片机程序

本文详细介绍了如何使用Keil C51的printf函数高效调试STC单片机程序,包括硬件连接、printf重定向、结构化输出设计和高级调试技巧。通过串口助手实现数据可视化,提升开发效率,特别适合STC15系列单片机开发者。

weixin_30681615的博客 264

STC8单片机串口打印调试,为什么你的printf不工作?TI标志位避坑指南

本文深入解析STC8单片机串口打印调试中printf不工作的常见问题,重点讲解TI标志位的关键作用及避坑方法。通过两种实用解决方案(初始化置位TI和完整发送函数实现),帮助开发者快速解决串口输出异常问题,并提供中断环境下的高级调试技巧与性能优化建议。

weixin_42632434的博客 395

51单片机(STC8)-- 串口配置及串口重定向(printf)

STC8H系列单片机串口通信和串口重定向配置

General_s 1万+

单片机-#define XBYTE ((unsigned char volatile xdata *) 0)

#define XBYTE ((unsigned char volatile xdata *) 0) 定义 XBYTE 为 指向 xdata 地址空间unsigned char 数据类型的指针,指针值为0 这样,可以直接用XBYTE[0xnnnn]或*(XBYTE+0xnnnn)访问外部RAM了。

STC15单片机串口调试:printf重定向的3种实现方式与常见坑点解析

本文详细解析了STC15单片机串口调试中printf重定向的3种实现方式,包括sprintf组装字符串、putchar函数重定向和MicroLIB与fputc重定向,并深入探讨了常见坑点与解决方案。通过对比分析各方法的优缺点,帮助开发者选择最适合的方案,实现高效稳定的串口调试输出。

weixin_30379531的博客 604

企业AI Agent的审计与合规

本文将带你从**“0基础理解企业AI Agent审计与合规”到核心概念梳理:用大白话+学术定义拆解什么是“企业AI Agent”、“可审计性(Auditability)”、“可解释性(Explainability,XAI)≠可审计性”、“合规性(Compliance)”、“黑盒拆解的三层维度”等硬核但必须掌握的概念;风险与合规背景:从**内部风险(数据泄露、误操作、模型偏差)和。

Java大师兄的博客 301

树莓派烧录验证失败:跳过验证步骤实现成功启动的实用技巧

本文针对树莓派烧录系统时常见的验证失败问题,提供了跳过验证步骤实现成功启动的实用技巧。通过分析Windows与Linux文件系统差异导致的SD卡验证报错,指导用户在烧录完成后立即关闭验证窗口,或使用BalenaEtcher等第三方工具规避问题,确保树莓派正常启动。

yyy34的博客 949

51单片机(STC15W408AS)映射printf函数 串口收发实现

前提:实现串口收发数据 /************************************************* *函数名称:char putchar(char c) *功 能:映射printf *参 数:char c ...

我是唐 9100

android11-修改屏幕显示方向和触摸方向

参数0表示12点钟方向显示参数90表示3点钟方向显示参数180表示6点钟方向显示参数270表示9点钟方向显示。

Paper_Love的博客 2118

51单片机printf重定向

从keil的帮助文档里我们可以看到,printf是基于putchar实现的,所以我们只要重新实现putchar,就可以实现printf的重定向,即可以将printf用在其他串口上。 putchar的函数实现在…/C51/LIB下可以找到。 #include <reg51.h> #define XON 0x11 #define XOFF 0x13 /* * putchar (...

Qrpucp的博客 6006

ESP-IDF 利用ESP32构建智能音乐播放器(一)---------- 实现SD卡MP3文件的解码与播放

本文详细介绍了如何利用ESP32和ESP-IDF开发框架,从零开始构建一个智能音乐播放器。文章重点讲解了如何通过SD卡模块读取MP3文件,并集成Helix MP3解码库进行软件解码,最终通过I2S接口驱动音频模块实现播放。内容涵盖硬件连接、软件环境搭建、核心解码与输出逻辑,为嵌入式音频开发提供了完整的实战指南。

weixin_29163797的博客 234

CANoe连接Option Scope使用方法

本文档主要介绍如何使用CANoe Option .Scope捕获CAN总线上的物理波形,并利用眼图进行分析。

测试领域技术分享 1353

【STC15】利用库函数实现printf和scanf重载示例模板

【STC15】利用库函数实现printf和scanf重载示例模板

perseverance51博客 1266

qt实现OCC读取STEP模型并显示(附完整源码)

qt实现OCC读取STEP模型并显示(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1480

STC15-串口通信打印输出数据printf函数与sprintf函数

本文主要比较了printf和sprintf函数在STC15单片机串口通信中的应用差异。printf直接将格式化数据输出到屏幕,而sprintf将数据存入指定缓冲区。文章详细介绍了STC15串口1的初始化配置,包括波特率设置、中断处理和数据发送函数实现,并解析了相关寄存器(SCON、PCON、SBUF等)的功能。示例代码展示了如何使用sprintf格式化字符串并通过printf输出,为单片机串口通信开发提供了实用参考。

weixin_41226265的博客 1916

整理 钢琴 约翰·汤普森现代钢琴(大汤)

大汤

TS的博客 3996

【MATLAB】工业传送带速度闭环控制与张力联合仿真

本文基于MATLAB/Simulink平台,构建了工业传送带速度闭环控制与张力联合仿真系统。通过搭建驱动模块、机械传动模块、检测模块和控制模块,实现了速度与张力的协同控制。采用双PID调节器分别整定速度与张力参数,经联合调试后系统性能良好:速度跟踪误差小于±0.03m/s,张力波动控制在±30N内,负载扰动恢复时间仅0.3秒。研究提供了从建模到参数优化的完整工程方案,可直接应用于课程设计或工业实践,有效解决了传送带运行中速度偏差与张力波动的协同控制难题。

unber的博客 76

Keil C51重定向printf到串口

进行C/C++开发的时候我们都会需要打印调试信息,打印调试信息时我们习惯使用printf函数,但是在Keil C51环境下,由于我们的程序是下载到单片机里,使用printf函数时不能直接打印到串口上,这个时候就需要我们对printf函数输出重定向。

代码就是生产力!https://yannanxiu.cn/ 2万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

keil C51 重定向printf到串口

概述 进行C/C++开发的时候我们都会需要打印调试信息,打印调试信息时我们习惯使用printf函数,但是在Keil C51环境下,由于我们的程序是下载到单片机里,使用printf函数时不能直接打印到串口上,这个时候就需要我们对printf函数输出重定向。 重定向 重定向printf很简单,我们知道,printf函数是调用putchar实现字符数据传送的。我们只要重写putchar函数,就可以...

保持每天的清醒 2396

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SCT单片机打印printf

摘要:STC单片机与STM32的打印功能相似,只需添加stdio.h头文件并重定义putchar函数。示例代码展示了如何通过串口实现字符发送,其中UART1_SendByte函数将数据写入SBUF寄存器并等待发送完成。注意需根据实际串口配置修改代码,同时包含看门狗喂狗操作以避免复位。该实现方式简单,适用于STC单片机的串口打印功能开发。

weixin_56533319的博客 153

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

单片机printf函数调用一些该注意的

STC12C5410AD单片机在串口通信中,如果需要用printf函数通过串口进行数据的传输,并用上位机进行接收时,只需要对putchar()函数进行一次重写,这样加上头文件stdio.h,就可以在程序中调用printf函数了。大牛勿喷~~~~ #include #include #define uchar unsigned char #define uint unsigned i

zhangyangluna的专栏 965

精简版STC单片机串口程序(只有初始化和sendbyte)

摘要:本文分享两个函数构成的STC单片机串口发送程序,代码占用空间极小。不想调用stdio.h和printf但是还想用串口发送简单的调试信息?那就试试它吧!

ieeee.blog.youkuaiyun.com 1965
上一篇: How to Install MySQL 8.0 on Ubuntu 20.04
下一篇: STC8F/A系统时钟源选择外部时钟串口测试程序
armcsdn
博客等级 码龄11年 275粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

armcsdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值