51 microcontroller serial communication uses two methods similar to the printf function

Publisher:科技革新者Latest update time:2016-05-18 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
 

Today I will briefly talk about how to The use of "printf" function in 51 microcontroller: including using the built-in printf function and writing a printf function by yourself. Before pasting the code, I will introduce some relevant knowledge, which is mainly used to write the printf function by yourself.

①C language Function: vsprintf,


Its prototype is int vsprintf(char *string, char *format, va_list param);, which is used to write param into the string according to the format format, so it can be used to convert any format data into string data, such as The program to convert the integer 97 into the ASCII code 97 is as follows: vsprintf(string, "%d", 97). Of course, there is one more thing to note: using sprintf in keil requires the header file stdio.h (of course, here too You can use sprintf, which has almost the same effect and only needs slight modifications (no more introduction). Having said that, let’s talk about another function itoa. In fact, it is simpler than vsprintf. Its prototype is char *itoa(int value, char *string, int radix), which is used to write value to string in radix system. In the string, the header file stdlib.h needs to be included when using it, but it cannot be used in keil. The header file does not contain itoa. Even if it is imported from VC, it still doesn't work. I don't know the reason at the moment.

②Variable parameter function

Specifically, these are the functions va_start, va_arg, va_list, and va_end in stdarg.h. These parameters are used to open up a memory area and can be used with vsprintf. However, they use a large amount of memory and require a certain amount of RAM in the microcontroller. , otherwise the program will not be able to run even if it can be compiled and passed. See here for usage http://blog.csdn.net/googlemi/article/details/8988567

③Internal expansion RAM

Definition: The data memory integrated inside the microcontroller is physically internal, but logically external. When accessing, MOVX or xdata needs to be used. For details, see the STC8051 manual, as shown below

51 microcontroller serial communication uses two methods similar to the printf function
 

 

51 microcontroller serial communication uses two methods similar to the printf function
 

 

 

: Internal RAM (256byte) consists of three parts: low 128byte, high 128byte and special function register area. Pay special attention to that unlike 51, its special function register overlaps with the high 128byte address, but is physically separated. All internally available RAM There are 256byte, so the total internal RAM size that can be obtained so far is: 256byte+1024byte=1280byte

Having said so much, I won’t go into details below, let’s go directly to the program.

"1" Directly use the printf function that comes with the system: pay special attention to the need to set TI=1, otherwise it will not be sent. The procedure is as follows:

//This program is mainly used for uart sending (the proteus terminal cannot display Chinese characters, but the serial port assistant can), enter the newline character \nnewline
#include
//stdio.h, string.h are used for printf function prototype
#include


void delay(unsigned int z);
void uart_init(void);//Serial port initialization

int main(void)
{
	int a=99;
	char *string="abde";
	uart_init();
	while(1)
	{
		printf("%d %x %c %s %p\n",a,a,(char)a,string,string);
		delay(1000);
	}
	return 0;
}

void uart_init(void)
{
	TMOD=0x20;//That is 0010 0000, timer/counter 1, working mode 2
	TH1=0xfd;//Set the baud rate to 9600
	TL1=0xfd;
	TR1=1;//Start timer/counter 1
	
	SCON=0x50; //0101 0000. Serial port working mode 1, allowing serial control
	PCON=0x00;//Set SMOD=0
	IE=0x90; //CPU allows interrupts, serial allows interrupts
	
	TI=1;//If you use printf directly, you must add this sentence to achieve sending.
}

void delay(unsigned int z)
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

"Two" Write a function similar to printf yourself: uart_printf

However, this situation takes up a lot of RAM. Because a large array needs to be opened, an expanded 51 microcontroller needs to be used. Ordinary AT89C51 and STC89C52 will cause problems such as insufficient memory, stack overflow, etc., so the following programs are based on STC12C5A60S2, because it contains internally expanded 1024byte RAM, which can be used to store large arrays

//This program is mainly used for uart sending (proteus cannot be simulated, but it can actually be run), enter the newline character\nnewline
#include
//stdio.h, stdarg.h are used for vsprintf function prototype
#include
#include

void delay(unsigned int z);
void uart_init(void);//Serial port initialization
void sendbyte(unsigned char c);
void sendstring(unsigned char *string);
void uart_printf(const char *fmt,...);

int main(void)
{
	int a=99;
	uart_init();
	while(1)
	{
		uart_printf("Decimal:%d Hexadecimal:%x character format:%c\n",a,a,a);
		delay(1000);
	}
	return 0;
}

void uart_init(void)
{
	TMOD=0x20;//That is 0010 0000, timer/counter 1, working mode 2
	TH1=0xf3;//Set the baud rate to 2400
	TL1=0xf3;
	TR1=1;//Start timer/counter 1
	
	SCON=0x50; //0101 0000. Serial port working mode 1, allowing serial control
	PCON=0x00;//Set SMOD=0
	IE=0x00; //Since it is a query mode, interrupts need to be disabled. CPU does not allow interrupts, and serial interrupts are not allowed.
	
}

void delay(unsigned int z)
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

void sendbyte(unsigned char c)
{
	if(c=='\n')//If you encounter \n, break the line
	{
		//Send CR(carriage return)
		SBUF=0x0D;
		while(!TI);//Waiting for sending to complete
		TI=0;
		
		//Send LF(NL line feed,new line)
		SBUF=0x0A;
		while(!TI);//Waiting for sending to complete
		TI=0;		
	}
	else
	{
		SBUF=c;
		while(!TI);//Waiting for sending to complete
		TI=0;
	}
}

void sendstring(unsigned char *string)//Here *string is equivalent to an array
{
	while(*string!='\0')//Determine whether it reaches the end of the string
	{
		sendbyte(*string);
		string++;
	}
}

void uart_printf(const char *fmt,...)
{
	va_list ap;
	char xdata string[1024];//Accessing internal extended RAM, non-accessing external RAM, cannot exceed the internal extended RAM size (here is 1024)
	
	va_start(ap,fmt);
	vsprintf(string,fmt,ap);//The sprintf function can also be used here. The usage is similar and can be slightly modified. It is omitted here.
	sendstring(string);
	va_end(ap);
}

Finally, a brief summary: The first method will have problems when working in the interrupt mode, because the bottom layer is implemented by calling the putchar function. The working mode is interrupt, but it is relatively simple and can be simulated through proteus; the second method is more complete, but The program is relatively complex and cannot be simulated using proteus, but it can actually work.

Reference address:51 microcontroller serial communication uses two methods similar to the printf function

Previous article:Notes on 51 MCU serial communication
Next article:Flex and 51 MCU socket communication strategy

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号