当前位置:首页 > 芯闻号 > 技术解析
[导读]单片机编程软件的使用频率极高,采用单片机编程软件,可制造诸多系统。对于单片机编程软件,小编做过诸多介绍。本文对于单片机编程软件的介绍基于Keil,主要在于介绍该单片机编程软件是如何处理库函数以及寄存器的关系的。

单片机编程软件的使用频率极高,采用单片机编程软件,可制造诸多系统。对于单片机编程软件,小编做过诸多介绍。本文对于单片机编程软件的介绍基于Keil,主要在于介绍该单片机编程软件是如何处理库函数以及寄存器的关系的。如果你对本文即将探讨的内容存在兴趣,不妨继续往下阅读哦。

在一个芯片系统里,uart的驱动是厂商自己写好的,那他们是怎么关联printf到uart的呢?有人说,printf最终是调用了putchar,小编搜索了源码,没有这个函数,估计是开发工具,像KeilC u3,里面已经集成了putchar。于是小编奇怪,这个工具怎么知道厂商哪个函数时uart的,有没有命名规则要求?好像没有,看了下面的讨论,估计是通过UART的收发寄存器来关联的。小编猜想应该是在某个地方,keilc关联了系统的寄存器列表,找到了串口的寄存器的地址,然后putchar操作该寄存器,就相当于操作了厂商或者开发者自定义的uart_write_byte.uart_read_byte.

在你配置完串口的时候首先写一个数到SBUF寄存器中然后在用printf函数打印就可以,当让这个顺序是不可以变的,如果你想在追问细节为什么,小编只能告诉你这应该是开发环境决定的,这一点小编就理解这么多,如果有大侠给出更好的解释小编也一起共勉。

其实也不用首先写一个数据到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函数事实上是调用putchar输出字符的。之所以能输出到串口上,就是因为putchar函数把字符通过串口输出。这是keil中putchar最简单的版本,其他版本也一样,看函数就明白为什么要先让TI=1;了,楼主写的那个SBUF=0,原理是相同的,写入了数据,那么TI就等于1了,然后就可以使用putchar函数和printf函数了。putchar函数的源码在{keil安装目录下}\C51\LIB文件夹里的PUTCHAR.C文件里,另外在keil的帮助文档里有说明。

char putchar (char c) {

while (!TI);

TI = 0;

return (SBUF = c);

}

小编在某个CortextM3的源码里的debug.c找到了fputc。应该说,某些系统是通过fputc建立联系,而不是putchar的。如下:

void fputc_hook(char ch)

{

if (DebugType == 0)

{

UARTWriteByte(ch, 1000);

}

else

{

VirtualUartWrite(ch);

}

}

int fputc(int ch, FILE *f)

{

uint8 dgbBuffer[DEBUG_TIME_LEN];

uint32 tmpcnt, i;

if (ch == '\n')

{

tmpcnt = SysTickCounter;

for (i = 0; i < DEBUG_TIME_LEN; i++)

{

dgbBuffer[i] = tmpcnt % 10;

tmpcnt = tmpcnt / 10;

}

fputc_hook('\r');

fputc_hook('\n');

fputc_hook('[');

for (i = 0; i < DEBUG_TIME_LEN; i++)

{

fputc_hook(dgbBuffer[DEBUG_TIME_LEN - 1 -i]+0x30);

if (DEBUG_TIME_LEN - 1 -i == 2)

{

fputc_hook('.');

}

}

fputc_hook(']');

return OK;

}

fputc_hook(ch);

return OK;

}

在实际工作中,遇到了这么一个问题,需要向不同的串口传输ASCII码,无疑使用printf函数是最方便的。然而printf打印出的信息无法选择出口。在网上搜到的程序,printf要调用fputc函数发送字符。该函数如下:

int fputc(int ch, FILE *f)

{

/* e.g. write a character to the USART */

USART_SendData(USART1, (uint8_t) ch);

/* Loop until the end of transmission */

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)

{}

return ch;

}

入口参数有字符和字符要输出到的文件指针。根据搜索,printf函数输出到stdout,而fprintf可以指定字符到达的文件。可FILE结构体中,没有一个是与串口相关的。

typedef struct {

char *fpos; /* Current position of file pointer (absolute address) */

void *base; /* Pointer to the base of the file */

unsigned short handle; /* File handle */

short flags; /* Flags (see FileFlags) */

short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */

unsigned long alloc; /* Number of currently allocated bytes for the file */

unsigned short buffincrement; /* Number of bytes allocated at once */

} FILE;

该如何重定向呢?自己定义n个FILE*指针,并任意赋值。在fputc中利用if..else来做判断,代码如下:

FILE* FileUart1 = (FILE*)0x19;

FILE* FileUart2 = (FILE*)0x28;

int fputc(int ch, FILE *f) {

if ( f == FileUart1 ) {

USART_SendData(COM_USART[0], (uint8_t) ch);

while (USART_GetFlagStatus(COM_USART[0], USART_FLAG_TC) == RESET){}

}

else if ( f == FileUart2 ) {

USART_SendData(COM_USART[1], (uint8_t) ch);

while (USART_GetFlagStatus(COM_USART[1], USART_FLAG_TC) == RESET){}

}

}

这样,fprintf(FileUart1,...)和fprintf(FileUart2,...)便能向不同的串口发送数据。虽然没有真正做到重定向,但最初的目的还是达到了。

以上便是此次小编带来的“单片机编程软件”相关内容,通过本文,希望大家对Keil单片机编程软件如何处理库函数与寄存器间的关系具备一定的了解。如果你喜欢本文,不妨持续关注我们网站哦,小编将于后期带来更多精彩内容。最后,十分感谢大家的阅读,have a nice day!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭