一起学mini2440裸机开发(七)--UART高级实验,可变参函数

发布者:独行于世最新更新时间:2021-11-05 来源: eefocus关键字:mini2440  裸机开发  UART 手机看文章 扫描二维码
随时随地手机看文章

概述:

在C语言中,使用printf()进行格式化输出非常方便,例如,printf("%dn",a)可以将a的值以十进制的格式输出,然后换行。printff()函数的原型为:int printf(const char *format,...),在函数参数中的...表示可变参数,即输入参数的个数不确定(例如,printf("%dn",a)和printf("%d%dn",a,b)都可以使函数进行正确的输出),这种输入参数不确定的函数就叫可变参数。在UART中能不能自己写一个类似于 printf() 的函数(例如,Uart0_Printf("%d",a))呢?下面咱们就试图找到实现这种函数的方法。


实验内容:

本实验要实现的功能就是利用uart实现发送可变参数的功能。


实验代码结构如下图:

实验一共包含3个文件:main.c  uart.c  uart.h


main.c文件内容:


#include

#include"uart.h"


int main()

{   

    unsigned int a=10;       //系统时钟初始化,FCLK=400MHz,HCLK=100MHz,PCLK=50MHz

    Uart0_Init(115200);      //初始化并设置波特率为115 200

    while(1)

    {

       Uart0_Printf("Uart0_Printf test output is:%dn",a);

    }     

}


uart.c文件内容:


#include

#include

#include"uart.h"


#define PCLK   50000000

#define UART_BRD     (int)((PCLK/(baudrate*16))-1)


/***********************************************

*函数名称:void Uart0_Init(unsigned int baudrate)

*参数说明:baudrate:波特率

*返 回 值:无

*全局变量: 无

*功    能:对UART0进行初始化                         

************************************************/

void Uart0_Init(unsigned int baudrate)

{

     GPHCON&=~((3<<4)|(3<<6));  //GPH2--TXD0;GPH3--RXD0

     GPHCON|=((2<<4)|(2<<6));    //设置GPH2、GPH3为TXD0、RXD0功能

     GPHUP=0x00;                 //上拉电阻使能

      ULCON0|=0x03;              //设置数据发送格式:8个数据位,1个停止位,无校验位

      UCON0=0x05;                //发送模式和接收模式都使用查询模式

     UBRDIV0=UART_BRD;         //设置波特率,其中波特率作为一个参数传递到该初始化函数

     URXH0=0;          //将URXH0清零

}


/***********************************************

*函数名称:void putc(unsigned char c)

*参数说明:c:通过串口接收到的字符,注意这里是8位数据

*返 回 值:无

*全局变量: 无

*功    能:将通过串口接收到的字符发送给PC机并显示在

*          串口调试工具。                

************************************************/

void putc(unsigned char c)

{

     UTXH0=c;

     while(!(UTRSTAT0&(1<<2)));    //等待发送完成

}


/***********************************************

*函数名称:unsigned char getc(void)

*参数说明:无

*返 回 值:c:通过串口接收到的字符,注意这里是8位数据

*全局变量: 无

*功    能:接收并保存通过串口输入的数据                         

************************************************/

unsigned char getc(void)

{

     unsigned char c;

     while(!(UTRSTAT0&(1<<0)));     //查询是否接收到有效数据

     c=URXH0;

     return c;

}

/***********************************************

*函数名称:static void Uart0_SendByte(int data)

*参数说明:data:一个字节的数据

*返 回 值:无

*全局变量: 无

*功    能:向串口发送一个字节的数据。这个函数只在本

*          C文件内使用,不被其他文件所调用,故使用

*     static来修饰。                 

************************************************/


static void Uart0_SendByte(int data)

{

     if(data=='n')      //注意,在超级终端中使用的换行符是'r',因此当遇到'n'时

    {                        //需要将其转换为'r'

       while(!(UTRSTAT0&(1<<2)));    //等待发送完成

       UTXH0='r';  

    }

    while(!(UTRSTAT0&(1<<2)));    //等待发送完成完成后,将新发送

    UTXH0=data;                         //的数据写入发送寄存器

}

/***********************************************

*函数名称:static void Uart0_SendString(char *pt)

*参数说明:pt:指针,指向将要发送的数据所在数组的地址

*返 回 值:无

*全局变量: 无

*功    能:发送字符串                 

************************************************/

static void Uart0_SendString(char *pt)

{

   while(*pt)

   {

      Uart0_SendByte(*pt++); 

   }

}

/***********************************************

*函数名称:void Uart0_Printf(const char *fmt,...)

*参数说明:可变参数

*返 回 值:无

*全局变量: 无

*功    能:将()的内容通过串口发送并在PC机显示                

************************************************/

void Uart0_Printf(const char *fmt,...)

{

   va_list ap;                   //定义了一个指向可变参数列表指针

   char string[50];          //存储要发送的内容


   va_start(ap,fmt);     //是参数列表指针ap指向函数参数列表中的第一个可变参数

   vsprintf(string,fmt,ap);

   va_end(ap);              //清空参数列表

   Uart0_SendString(string);   //将该缓冲区中的数据打印到串口中

}


 


    下面重点讲解一下Uart0_Printf(const char *fmt,...)


   void Uart0_Printf(const char *fmt,...)

   {

       va_list ap;                  //定义了一个指向可变参数列表指针

       char string[50];         //存储要发送的内容


       va_start(ap,fmt);     //是参数列表指针ap指向函数参数列表中的第一个可变参数

       vsprintf(string,fmt,ap);

       va_end(ap);             //清空参数列表

       Uart0_SendString(string);  //将该缓冲区中的数据打印到串口中

  }


理解这个函数需要了解下面的基础知识:


可变参数的列表分为两部分:固定参数和个数可变的可变参数。函数中至少有一个固定参数;可变参数由于个数不确定,声明用"..."表示。


   ●   va_list  ap:定义了一个指向可变参数列表指针。


   ●   va_start(ap,argN):使参数列表指针ap指向函数列表中的第一个可变参数,argN是最后一个固定参数。例如,当函数的声明是void va_test(char a,char b,...),则它的固定参数依次是a,b,最后一个固定参数argN为c,因此就是a_start(ap,c)。


   ●   va_end(ap):清空参数列表,并置参数指针ap无效,该宏的作用是结束可变参数的获取。


   ●   vsprintf()函数原型为int vsprintf(char *string,char *format,va_list param),其作用是将param按格式format写入字符串string中。


因此,上述函数的基本流程是:


   ●  先开辟一块区域存储可变参数


   ●  然后,调用vsprintf()函数将可变参数按照指定的格式复制到缓冲区中。


   ●  最后,调用Uart0_SendString()函数将该缓冲区中的数据打印到串口中。 


将以上3个文件,复制完后,再编译调试后,可以看到串口的效果:

我将该工程文档上传到:可自行下载点击打开链接


注意:老生长谈


     ①将S3C2440.s中的CLOCK_SETUP     EQU     0 修改为  CLOCK_SETUP     EQU     1


     ②复制并修改Ext_RAM文件。

关键字:mini2440  裸机开发  UART 引用地址:一起学mini2440裸机开发(七)--UART高级实验,可变参函数

上一篇:一起学mini2440裸机开发(九)--ARM中断控制系统
下一篇:一起学mini2440裸机开发(四)--S3C2440定时器学习

推荐阅读最新更新时间:2024-11-07 08:30

mini2440之S3C2410 SDRAM寄存器初始化设置
板子是s3c2410,使用两片容量为32MB、位宽16bit的HY57V561620CT-H芯片拼成容量为64M、32bit的SDRAM存储器。根据2410datasheet,要使用SDRAM需配置13个寄存器,以下逐个来看: 1、 BWSCON:Bus width & wait status control register总线位宽和等待状态控制寄存器。 此寄存器用于配置BANK0 – BANK7的位宽和状态控制,每个BANK用4位来配置,分别是: ● ST(启动/禁止SDRAM的数据掩码引脚。对于SDRAM,此位置0;对于SRAM,此位置1) ● WS(是否使用存储器的WAIT信号,通常置0为不使用) ● DW(两位,设置位宽
[单片机]
Eclipse开发调试ARM裸机程序(三)C语言LED_LINUX使用DNW
第二个程序用C语言实现的LED程序,Startup.S是启动代码;led_on_c.c是C语言实现的LED点灯程序。代码分别如下: @ @ File:Startup.S @ 功能:通过它转入C程序 @ .text .global _start _start: ldr r0, =0x56000010 @ WATCHDOG寄存器地址 mov r1, #0x0 str r1, @ 写入0,禁止WATCHDOG,否则CPU会不断重启 ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
[单片机]
Eclipse<font color='red'>开发</font>调试ARM<font color='red'>裸机</font>程序(三)C语言LED_LINUX使用DNW
使用u-boot_2016_01启动mini2440(二)uboot内存分布
启动内存的分布主要是在board_init_f内划分的: 按照我的代码,分布如下: 代码log: U-Boot 2016.01-g3401853-dirty (Apr 04 2016 - 08:06:26 -0400) U-Boot code: 33A00000 - 33A7BEF4 BSS: - 33ACAAE4 CPUID: 32440001 FCLK: 405.600 MHz HCLK: 101.400 MHz PCLK: 50.700 MHz DRAM: Monitor len: 000CAAE4 Ram size: 04000000 Ram top: 34000000 TLB table from 3
[单片机]
使用u-boot_2016_01启动<font color='red'>mini2440</font>(二)uboot内存分布
stm32 uart清除中断时机
今天遇到了在调试之前开发人员写的stm32程序时,发现uart1(即console)不能连续接收字符,一旦连续接收字符就会重启? 定位问题: 根据现状可以知道肯定是中断引起的问题,即第一个中断还没有处理完(中断标志位没有清除),第二个中断又来了,进而导致 重启现象。 修改前: void USART1_IRQHandler(void) { unsigned short temp; while(USART_GetITStatus(USART1, USART_IT_RXNE) == RESET); temp = USART_ReceiveData(USART1); if(temp == '\r') printf( \
[单片机]
STM32的HAL库的 I2C和UART使用函数
void I2C_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr,uint16_t NumByteToWrite){ //HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)DeviceAddr, pBuffer, NumByteToWrite, 1000);//1000ms 1s 100K字节s } void I2C_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead){ uint8_
[单片机]
mini2440裸机程序--LED灯(C语言)
看了mini2440配套光盘里面的例子,C语言的点亮LED程序略显复杂。当时打开工程,看到这么多文件,顿时傻了眼。还好自己能够有良好的心态,慢慢弄。 对于点亮LED灯的C语言程序,相对于汇编程序,除了MDK系统自动添加的启动代码S3C2440.S ,其余的也就和汇编程序的步骤一样了。现在就把程序附在下面: #define rGPBCON (*(volatile unsigned long *)0x56000010) #define rGPBDAT (*(volatile unsigned long *)0x56000014) #define rGPBUP (*(volatile unsigned long *)0x5
[单片机]
linux-2.6.32在mini2440开发板上移植 移植UDA1341 音频驱动
1 在初始化文件中加入UDA1341 设备结构 Linux-2.6.32.2 已经完美的支持UDA1341 音频芯片的驱动, 我们只要在arch/arm/mach-s3c2440/mach-mini2440.c 文件中注册UDA1341 平台设备的控制端口就可以了,打开mach-mini2440.c,添加如下内容: ;在文件首部添加头文件 #include sound/s3c24xx_uda134x.h ;在LCD 平台设备后面添加UDA1341 设备结构 static struct s3c24xx_uda134x_platform_data s3c24xx_uda134x_data = { .l3_clk =
[单片机]
赛普拉斯推出低功耗 USB 与 UART 桥接控制器
2012 年 6 月 13 日,北京讯,加州圣何塞讯——赛普拉斯半导体公司(纳斯达克股票代码:CY)日前宣布推出全新 EZ-USB® USB-UART 桥接控制器 (CY7C64225),以进一步丰富其市场领先的 USB 产品系列。此新型器件可提供低成本、低功耗解决方案,能够将传统 UART (通用异步收发器)接口转换成为全速 USB 2.0 接口。采用全新解决方案无需额外的固件或软件开发工作,不仅可显著加速产品上市进程,还可帮助系统制造商降低开发成本。如欲了解有关此全新器件的更多详情,敬请访问:www.cypress.com/go/USB-UART。 EZ-USB USB-UART 桥接控制器可提供低至 6 µA 的休眠电流。
[家用电子]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved