做嵌入式的基本上都清楚,板子基本上跑起来了,第一个肯定要配置的是串口,便于我们后面调试信息的输出,和一些系统参数的输出,让我们有更直观看见程序的运行。

—————————————————————————————————————————————

硬件平台:TQ2440 (S3C2440A)

开发环境:ADS1.2

时      间:2010-12-12

—————————————————————————————————————————————

1:硬件电路:

                  底板电路                           核心板上的连接管脚

由于TQ2440的板子上只引出了一个串口,也就是用的UART0作为COM1,所以我吗只需要配置相关的引脚为串口功能即可。

接着参考2440的说明文档:

所以把GPH相关的GPH0-3都配置为第二功能UART功能。即可以上至完成了管脚的配置,接着对UART的功能进行配置。

A:UART寄存器:

从2440的数据手册上我们可以知道他的寄存器的地址都是连接着的,所以我们直接用结构体来表示,因为他有3个串口,所以,我们这里就可以用3个不同的结构体指针来操作不同的寄存器。代码如下:

   1: #define IO_CON_BASE 0x56000000
   2: #define IO_DAT_BASE 0x56000004
   3:  
   4: #define UART0_BASE  0x50000000  // UART0 Base Address
   5: #define UART1_BASE  0x50004000  // UART1 Base Address
   6: #define UART2_BASE  0x50008000  // UART2 Base Address
   7:  
   8: #define REG8(x)  (*((volatile unsigned char  *)(x)))
   9: #define REG16(x) (*((volatile unsigned short *)(x)))
  10: #define REG32(x) (*((volatile unsigned long  *)(x)))
  11:  
  12: typedef volatile unsigned char  reg8;
  13: typedef volatile unsigned short reg16;
  14: typedef volatile unsigned long  reg32;
  15:                         
  16: /*
  17: GPIO_CFG_SET说明:   group--表示是那组IO(注意没有GPA)
  18:                     index--表示这组中的那个引脚   
  19:                     type --表示是配置为输入还是输出等其他功能
  20: */
  21: #define GPIO_CFG_SET(group,index,type) do{\
  22:                         (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))&=~(0x3<<index<<1);\
  23:                         (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))|=(type<<index<<1);\
  24:                         }while(0)
  25:                         
  26: /*
  27: GPIO_DAT_SET说明:   group--表示是那组IO(注意没有GPA)
  28:                     index--表示这组中的那个引脚   
  29:                     val  --表示对此引脚写入的数据
  30: */
  31: #define GPIO_DAT_SET(group,index,val) do{\
  32:                         (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))&=~(0x1<<index);\
  33:                         (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))|=(val<<index);\
  34:                         }while(0)
  35: /*
  36: 因为GPA的控制寄存器,每个引脚只只占用一位,所以为了能统一这里,就没有把
  37: GPA加进来,而后面的GPB-GPJ的控制寄存器每个引脚对应2位
  38: */                        
  39: enum{GPB=1,GPC,GPD,GPE,GPF,GPG,GPH,GPI,GPJ};
  40: /*
  41: 从GPB开始由于用两位表示此引脚的功能所以有四种可能
  42: 0代表INPUT,1代表OUTPUT,2代表第三功能,3代表第四功能
  43: */
  44: enum{INPUT=0,OUTPUT,THI_FUNC,FOR_FUNC};
  45: /*
  46: 定义高低电平
  47: */
  48: enum{LOW=0,HIG};
  49:  
  50: // UART Registers
  51: typedef struct {
  52:   reg32 ULCON;              // UART Line Control          由于控制数据格式,常用的为N-8-1模式 
  53:   reg32 UCON;               // UART Control                控制UART的工作状态,例如DMA,中断等
  54:   reg32 UFCON;              // UART FIFO Control        控制UART的FIFO,这里没有用到
  55:   reg32 UMCON;          // UART MODEM Control    在MODEM模式下的控制寄存器,这里没有用到
  56:   reg32 UTRSTAT;        // UART Tx/Rx Status        UART发送和接受状态寄存器
  57:   reg32 UERSTAT;        // UART Error Status            UART错误状态寄存器
  58:   reg32 UFSTAT;             // UART FIFO Status        UART---FIFO状态寄存器
  59:   reg32 UMSTAT;         // UART MODEM Status    UART---MODEM状态寄存器
  60:   reg8  UTXH;               // UART Tx Hold                UART发送数据寄存器 ##注意这里是一个char类型的
  61:   reg8  pad0[3];
  62:   reg8  URXH;               // UART RX Buffer            UART接受数据寄存器 ##注意这里是一个char类型的
  63:   reg8  pad1[3];
  64:   reg32 UBRDIV;             // UART Baud Rate Divisor UART的波特率产生器的分频率
  65: } regUART;
  66:  
  67: #define pUART0 ((regUART *)UART0_BASE)
  68: #define pUART1 ((regUART *)UART1_BASE)
  69: #define pUART2 ((regUART *)UART2_BASE)

2:2440的UART的配置

上面已经把相关的寄存器介绍的很清楚了,所以这里的配置就直接给出代码了,因为可以直接参考数据手册得到:

   1: void uart_init(void)
   2: {
   3:     //设置GPH[0..3]为uart0的输出引脚
   4:     GPIO_CFG_SET(GPH,0,THI_FUNC);
   5:     GPIO_CFG_SET(GPH,1,THI_FUNC);
   6:     GPIO_CFG_SET(GPH,2,THI_FUNC);
   7:     GPIO_CFG_SET(GPH,3,THI_FUNC);
   8:     
   9:     pUART0->ULCON=    0x03;   //N-8-1
  10:     pUART0->UCON=    0x245; //中断和查询模式
  11:     pUART0->UFCON=    0x0;    //No Use
  12:     pUART0->UMCON=    0x0;      //No Use
  13:     pUART0->UBRDIV=    26;      //当前板子的速度是FCLK:400M,HCLK=100M,PCLK=50M,UATR=115200
  14: }

   这样串口就能工作起来的了,自己在把链接串口工具配置成相同的波特率就能正常工作了。

3: 相关代码的实现

 接下来就是串口发送和接受数据的一些功能函数的实现了,下面也只实现了一些简单的函数:

输出部分:

   1: void u_printf(char *fmt,...)  //格式化输出
   2: {
   3:     va_list ap;
   4:     char str[100];
   5:     va_start(ap,fmt);
   6:     vsprintf(str,fmt,ap);
   7:     send_str(str);
   8:     va_end(ap);
   9: }
  10: void send_str(char *p_str)   //发送一个字符串
  11: {
  12:     while(*p_str!='\0')
  13:     {
  14:         if(*p_str=='\n')
  15:         {
  16:             send_char('\r');
  17:         }
  18:         
  19:         send_char(*p_str);
  20:         p_str++;
  21:     }        
  22: }
  23: void send_char(char cc)    //发送一个字符
  24: {
  25:     while(!(pUART0->UTRSTAT& 0x2));
  26:     pUART0->UTXH=cc;
  27: }

输入部分:

   1: char get_char(void)             //接受一个字符
   2: {
   3:     char cc;
   4:     while(!(pUART0->UTRSTAT& 0x1));
   5:     cc=pUART0->URXH;
   6:     return cc;
   7: }
   8:  
   9: void get_str(char *str)    //接受一个字符串
  10: {
  11:     /*
  12:     str_bak是为了存储str地址的,是为了在没有输入的情况下
  13:     输入退格,造成程序的崩溃
  14:     */
  15:     char *str_bak=str,cc; 
  16:     do{
  17:         cc = get_char();
  18:          if(cc=='\b')
  19:         {
  20:             if( (int)str_bak < (int)str)
  21:             {
  22:                 //u_printf("\b \b");
  23:                 send_char('\b');
  24:                 send_char('\b');
  25:                 str--;
  26:             }
  27:         }
  28:         else 
  29:         {
  30:             *str++ = cc;
  31:             send_char(cc);
  32:         }
  33:     }
  34:     while(cc!='\r');
  35:     
  36:     *str = '\0';
  37:     send_char('\n');
  38: }

4:彩色输出的实现

在公司的调试东西有时候打印的东西太多了,是在没办法找,所以最后实现了这个彩色打印的方法,便于迅速找到自己想得到的打印消息,从而提高工作效率。其彩色打印的原理为:

以下内容来自网上:

+-----------------------------------------------------------------------------------------------+

在 ANSI 兼容终端(例如 xterm、rxvt、konsole 等)里, 可以用彩色显示文本而不仅仅是黑白。
下面的语句就输出高亮的黑色背景的绿色字。
printf("\033[1;40;32m%s\033[0m", Hello,world!\n);
\033 声明了转义序列的开始,然后是 [ 开始定义颜色。后面的 1 定义了高亮显示字符。然后是背景颜色,这里面是40,表示黑色背景。接着是前景颜色,这里面是32,表示绿色。我们用 \033[0m 关闭转义序列, \033[0m 是终端默认颜色。
通过上面的介绍,就知道了如何输出彩色字符了。
下面是对于彩色字符颜色的一些定义:
前景   背景   颜色
---------------------------------------
30   40   黑色
31   41   紅色
32   42   綠色
33   43   黃色
34   44   藍色
35   45   紫紅色
36   46   青藍色
37   47   白色

代码   意义
-------------------------
0   终端默认设置
1   高亮显示
4   使用下划线
5   闪烁
7   反白显示
8   不可见

通过串口收发或显示字符时,我们使用的通常是字符的ASCII码。对于非控制字符,也即键入命令时我们可能使用到的命令字符,在控制台中我们使用了ASCII码值从0x20~0x7e之间的字符。对于控制字符,在常用字符ASCII码对照表中我们可以找到Enter键、Backspace(退格)键以及ESC键的ASCII码,但是却没有上下左右方向键以及Home、End键对应的ASCII码,通过对键盘输入字符的串口收发测试发现,如果在测试时按下了方向键则串口在每次按键后会连续发送出3字节数据,前两字节所有方向键的数据相同,分别是0x1b,0x5b,第3字节对应不同的按键,上下右左方向键分别对应的值为:0x41、0x42、0x43、0x44,Home和End键对应的值为0x48和0x4b。故要检测键盘是否键入了方向键,需要向串口连续读取三字节的数据,同理,要控制光标向左、向右移动或Home、End也需要连续一次向串口发送3字节数据。

+-----------------------------------------------------------------------------------------------+

所以我们只需要通过串口发送相应的指令就OK了,我为了方便将其封装为宏定义的格式:

   1: //######################Add by Dreamxi 彩色打印信息##################start
   2: //使用格式
   3: //cpfcpf(ALLOW_PUT,RED,("+----------------This is Dreamxi Uart cpf test --------------+"));
   4: //              |    |    |-------------------------------------------------------------|
   5: //       是否允许打印  |                                           |
   6: //                   |                                           |
   7: //                 打印颜色                                              |
   8: //                                                            打印内容
   9: #define ALLOW_PUT 1
  10: /*
  11: 前景          背景              颜色
  12: ---------------------------------------
  13: 30                 40              黑色
  14: 31                 41              紅色
  15: 32                 42              綠色
  16: 33                 43              黃色
  17: 34                 44              藍色
  18: 35                 45              紫紅色
  19: 36                 46              青藍色
  20: 37                 47              白色    
  21: */
  22: /*        红         绿   蓝   白   黄   紫红  青蓝 */
  23: enum {RED=0,GRE,BLU,WHI,YEL,ZH,GB};
  24:  
  25: #define cpf(DEBUG_MSG,COR,...) do{\
  26:     if(DEBUG_MSG==1)\
  27:     {\
  28:         if(COR==RED)\
  29:             {\
  30:                 u_printf("\033[1;31;40m");\
  31:                 u_printf(__VA_ARGS__);\
  32:             }\
  33:         else if(COR==GRE)\
  34:             {\
  35:                 u_printf("\033[1;32;40m");\
  36:                 u_printf(__VA_ARGS__);\
  37:             }\
  38:         else if(COR==BLU)\
  39:             {\
  40:                 u_printf("\033[1;34;40m");\
  41:                 u_printf(__VA_ARGS__);\
  42:             }\
  43:         else if(COR==WHI)\
  44:             {\
  45:                 u_printf("\033[1;37;40m");\
  46:                 u_printf(__VA_ARGS__);\
  47:             }\
  48:         else if(COR==YEL)\
  49:             {\
  50:                 u_printf("\033[1;33;40m");\
  51:                 u_printf(__VA_ARGS__);\
  52:             }\
  53:         else if(COR==ZH)\
  54:             {\
  55:                 u_printf("\033[1;35;40m");\
  56:                 u_printf(__VA_ARGS__);\
  57:             }\
  58:         else if(COR==GB)\
  59:             {\
  60:                 u_printf("\033[1;36;40m");\
  61:                 u_printf(__VA_ARGS__);\
  62:             }\
  63:         u_printf("\033[0m\r\n");\
  64:     }\
  65: }while(0)
  66: //######################Add by Dreamxi 彩色打印信息##################end

使用方法:

   1: cpf(ALLOW_PUT,RED,("+----------------This is Dreamxi Uart cpf test --------------+"));
   2: cpf(ALLOW_PUT,GRE,("+----------------This is Dreamxi Uart cpf test --------------+"));
   3: cpf(ALLOW_PUT,BLU,("+----------------This is Dreamxi Uart cpf test --------------+"));
   4: cpf(ALLOW_PUT,WHI,("+----------------This is Dreamxi Uart cpf test --------------+"));
   5: cpf(ALLOW_PUT,YEL,("+----------------This is Dreamxi Uart cpf test --------------+"));
   6: cpf(ALLOW_PUT,ZH,("+----------------This is Dreamxi Uart cpf test --------------+"));
   7: cpf(ALLOW_PUT,GB,("+----------------This is Dreamxi Uart cpf test --------------+"));

最后实现的效果图:

转载于:https://www.cnblogs.com/Dreamxi/archive/2010/12/12/1903804.html

TQQ2440第三节:串口相关推荐

  1. TQQ2440第三节:串口 MICRO2440 Fclk:Hclk:Pclk学习

    http://www.cnblogs.com/Dreamxi/archive/2010/12/12/1903804.html http://blog.chinaunix.net/space.php?u ...

  2. 详解 Qt 串口通信程序全程图文 (5)

    Qt 串口通信程序全程图文是本文介绍的内容,本节也是最后一节,本节主要讲述的是解决一下重要问题的说明: (下面所说的第一个程序是指第一节中写的那个程序,第二个程序是指第三节更改完后的程序,第三个程序是 ...

  3. 10-ESP8266 SDK开发基础入门篇--上位机通过串口控制ESP8266灯亮灭

    https://www.cnblogs.com/yangfengwu/p/11087618.html 其实这一节就是对上三节的综合测试 https://www.cnblogs.com/yangfeng ...

  4. 多个线程对串口读取 modbus_HART转Modbus转换器

    ▼更多精彩推荐,请关注我们▼ 第一节 功能说明 HART转Modbus模块实现将HART信号中的数字信号转换为符合Modbus RTU/ASCII标准的RS485信号和RS232信号,实现仪表的数据读 ...

  5. WIN32 API串口通信编程

    WIN32 API串口通讯实例教程 第一节实现串口通讯的函数及串口编程简介 API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作.常用函数及作用下: 函数 ...

  6. 【开发教程5】疯壳·ARM功能手机-串口实验教程

    ARM功能手机 --疯壳·开发板系列 串口实验教程 图1 第一节串口硬件电路 串口通过USB口及手环下载调试线引出,连接MCU的P12与P13引脚,如下图所示: 图2 第二节 UART寄存器 2.1 ...

  7. [基于STM32底盘控制与ROS上层导航小车制作] 第五节 实现STM32与ubuntu系统下的ROS串口DMA通信,传输底盘速度等信息

    系列文章目录 第一节 stm32电机驱动与编码器读取反馈 第二节 stm32电机pid控制 第三节 stm32线速度标定 第四节 stm32添加mpu6050得到angle角度 第五节 实现STM32 ...

  8. 昆仑通态屏幕制作(连载3)---基础篇(按钮串口发送)

    写在开始 经历了两天的努力,终于对这款嵌入式屏幕有了新的认识.下面做下类比: 单片机或者ARM: (1)main函数开始,进行INIT初始化: (2)while(1)循环: (3)外部或内部中断. 以 ...

  9. python第三方库之学习pyserial库--串口通信

    pyserial串口通信库 1.安装pyserial库 2.填写串口参数的注意事项 3.简单封装一下 4.碰到的bug 1.安装pyserial库 pip install pyserial versi ...

最新文章

  1. 2018-3-18Zookeep
  2. mysql中一个表最多能有几个auto_mysql--一个表上可以指定几个auto_increment
  3. python新闻系统_干货 | Python 实现新闻系统内容的增删改查功能
  4. pythondocumentation是什么_怎样阅读Python官方文档
  5. java连接数据库的基本操作
  6. [转载] Go语言的自重写程序
  7. java 反射 构造器_Java之类的构造器(反射)
  8. centos yum源_Linux入门珍藏课件系列第一讲:YUM源(图文)
  9. 从Chrome源码看JS Array的实现
  10. 联合查询(多表查询)
  11. 2017个人年终总结
  12. 码畜 码奴 码农 IT民工和IT其他工种的划分定义
  13. 手机扫描二维码登录原理
  14. [转]全图形PPT设计指南
  15. vs编写java_vs code编写java
  16. 视频剪辑,大师珍藏的素材都在这里!
  17. LCD液晶屏接口和显示器接口介绍
  18. 台湾清华大学物联网--004 物联网无线传输技术
  19. 杨校老师课堂之CSDN博客查找博文汇总-目录
  20. 2023跨年代码(烟花+自定义文字+背景音乐+雪花+倒计时)

热门文章

  1. python播放url音频_如何从URL播放mp3
  2. linux 双显示器双鼠标
  3. 鸿蒙os目前支持了哪些硬件,大佬终于把鸿蒙OS讲明白了,收藏了!
  4. java 拦截鼠标消息 循环_java – 由子组件拦截的swing鼠标侦听器
  5. 教师资格证面试计算机教案模板,2017年教师资格证面试教案模板
  6. python操作目录_Python语言目录操作一
  7. pako 压缩lottie动效资源方案
  8. SDN(五) Netgear R6220从刷机到配置 OpenvSwitch交换机
  9. AndroidVideoCache源码浅析
  10. 2008精选新年祝福语