Chinaunix首页 | 论坛 | 博客
  • 博客访问: 241574
  • 博文数量: 41
  • 博客积分: 928
  • 博客等级: 准尉
  • 技术积分: 550
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-01 10:07
文章分类
文章存档

2011年(41)

分类: 嵌入式

2011-04-04 21:32:08

串口通信还没弄完,等到全部弄完了在一起做一个总结,首先每天先记录一下现在的学习心得。

串口调试有几天了,发现串口调试还是比较难的,以后不管是调其他的什么器件都要遵循先容易的把最简单的框架弄好,再一步步的增加功能,一开始我试想 一步就把把串口通信弄完,直接写一个基于FIFO的中断串口通信,我承认我失败了,弄了好久没一点结果。弄串口通信还是先写一个不用FIFO的直接用查询 的程序,然后再加中断,最后写FIFO的中断程序。今天我写了是不用FIFO的中断程序,有几点要注意的地方。

1. 一定要先把手册看明白看清楚后在来写程序,其实中断的话如果简单的话只要设计几个寄存器,中断屏蔽寄存器INTMASK。开始我没看懂手册就开始写程序,把一堆的寄存器配置什么结果都没有。

2. 程序风格要好,注释要清晰,放在一个函数的前面,可以是这个函数的结构脉络,然后程序中间还可以插入一些必要的解释,这是我个人的理解,我觉得这样看起来会比较舒服。而且思路清晰。

3. 回到今天的程序,对于2440的中断一定要先清除中断挂起寄存器INTPND 和 SRCPND,如果遇到子中断的话还要先清除子中断,注意清除中断是给相应的中断位置1清除,二是先清除子中断然后清除父中断,这个是我给的叫法,理解就 好。三是即使是初始化中断寄存器也要先清除相应中断位,今天我就是因为这个地方而弄了好久。

今天要感谢赵春江老师的博客,写的非常好,今天是参考了赵老师的博客才发现是要初始化时清除中断。链接地址:

http://blog.csdn.net/zhaocj/archive/2010/03/10/5364412.aspx

今天就写到这里。20:27:31

S3C2440串口总结

ARM平台                    mini2440友善之臂

是否需要操作系统        否,裸机编程

串口通信总结如下

1. 基本知识概括

     S3C2440包含三个独立串口,UART0-3,支持系统时钟的115.2Kbps波特率,手册上说明用外部高频率时钟可以提高波特率,每个UART包含一个64Byte的FIFO。

     2440有多种通信模式,直接通信,FIFO,DMA,红外模式,自动流。详细见数据手册。

2. 把下面这个图看懂。即串口通信原理方框图

3. 配置好寄存器

其实配置寄存器的时候一定要把手册多看几篇,因为很多寄存器可能是硬件置位的只要你清除的,比如中断的几个挂起寄存器INTPND SRCPND这些寄存器就只要置1清除就好了。UART通信主要是配置寄存器。

4. 其他相关知识

中断,这个是很串口通信相关的,首先要把中断弄明白,还是要先清除中断挂起寄存器,还要注意顺序。

时钟,这个很重要,应该串口通信很重要的一点就是波特率,而波特率是由时钟控制的,其中串口的时钟一般是用PCLK时钟驱动,具体的2440的时钟以及相关配置在另一篇文章中已经说明白。

MMU,其实这个是与中断相关的,因为我们是裸机编程,中断的时候程序需要跳转,需要地址映射。

代码,

使用FIFO的中断串口通信代码

  1. #define    GLOBAL_CLK        1

  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "def.h"
  5. #include "option.h"
  6. #include "2440addr.h"
  7. #include "2440lib.h"
  8. #include "2440slib.h"
  9. #include "mmu.h"
  10. #include "profile.h"
  11. #include "memtest.h"

  12. #define baudrate 115200
  13. /**********************************
  14. void delay(int times)
  15. {
  16.     int i = 1000 ;
  17.     while(times--)
  18.     {
  19.         for(; i>0; --i)
  20.             ;
  21.     }
  22. }
  23. ************************************/
  24. /***********************************
  25. UART_int初始化led IO端口GPBCON5-8
  26. 初始化GPBHCON为串口通信
  27. 配置串口通信寄存器FIFOt通信
  28. 配置中断寄存器
  29. ************************************/
  30. void UART_int_init(void)
  31. {
  32.     //configuration LED IO port
  33.     rGPBCON &= ~(0xff<<10) ;
  34.     rGPBCON |= 0x55<<10 ;
  35.     //configuration GPHCON to UART
  36.     rGPHCON &= ~(0xf<<4) ;
  37.     rGPHCON |= 0xa<<4 ;
  38.     //configuration UART0 communication register
  39.     //8-bits,1 stop bit, no parity
  40.     rULCON0 = 0x03 ;
  41.     rUCON0 = 0x05 ;
  42.     rUFCON0 = 0x3f ;
  43.     //configuration UART baudrate
  44.     rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;
  45.     //clean interrupt bit
  46.     rSUBSRCPND |= 0x1 ;
  47.     rSRCPND |= 1<<28 ;
  48.     rINTPND |= 1<<28 ;

  49.     //open UART interrupt
  50.     rINTSUBMSK &= ~(0x1) ;
  51.     rINTMSK &= ~(0x1<<28) ;    
  52. }

  53. void UART_send_byte(int Tx_data)
  54. {
  55.     //wait Tx empty
  56.     while(!(rUTRSTAT0&0x2)) ;
  57.     
  58.     rUTXH0 = Tx_data ;
  59. }

  60. void UART_receive(void)
  61. {
  62.     char temp ;
  63.     //wait RX ready
  64.     while((rUFSTAT0&0x3F))
  65.     {
  66.         temp = rURXH0 ;
  67.         UART_send_byte(temp) ;

  68.     }
  69. }
  70. /*******************************************
  71. 中断处理函数
  72. 置1清除中断,注意顺序,先子中断后父中断
  73. 点亮led灯
  74. ********************************************/
  75. void __irq UART0_interrupt(void)
  76. {
  77.     rGPBDAT &= ~(0xf<<5) ;
  78.     //clean interrupt bit
  79.     rSUBSRCPND |= 0x1 ;
  80.     rSRCPND |= 1<<28 ;
  81.     rINTPND |= 1<<28 ;
  82.     //lighten led
  83.     rGPBDAT &= ~(0xf<<5) ;
  84.     UART_receive();
  85. }
  86. /*******************************
  87. void UART_send_string(char *str)
  88. {
  89.     while(*str)
  90.     {
  91.         //delay(200) ;
  92.         UART_send_byte(*str) ;
  93.         str++ ;
  94.     }
  95. }
  96. *******************************/

  97. /*******************************************************************
  98. 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
  99. 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
  100. 分频比,确定好PCLK时钟。
  101. ********************************************************************/
  102. int Main(void)
  103. {
  104.     MMU_Init();
  105.     ChangeMPllValue(127,2,1);        //405MHZ
  106.     ChangeClockDivider(13,12); //1:3:6    
  107.     UART_int_init() ;
  108.     while(1)
  109.     {
  110.         pISR_UART0 = (U32)UART0_interrupt ;
  111.     }
  112.     return 0 ;
  113. }

使用中断但不使用FIFO的代码

  1. #define    GLOBAL_CLK        1

  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "def.h"
  5. #include "option.h"
  6. #include "2440addr.h"
  7. #include "2440lib.h"
  8. #include "2440slib.h"
  9. #include "mmu.h"
  10. #include "profile.h"
  11. #include "memtest.h"

  12. #define baudrate 115200
  13. /**********************************
  14. void delay(int times)
  15. {
  16.     int i = 1000 ;
  17.     while(times--)
  18.     {
  19.         for(; i>0; --i)
  20.             ;
  21.     }
  22. }
  23. ************************************/
  24. /***********************************
  25. UART_int初始化led IO端口GPBCON5-8
  26. 初始化GPBHCON为串口通信
  27. 配置串口通信寄存器
  28. 配置中断寄存器
  29. ************************************/
  30. void UART_int_init(void)
  31. {
  32.     //configuration LED IO port
  33.     rGPBCON &= ~(0xff<<10) ;
  34.     rGPBCON |= 0x55<<10 ;
  35.     //configuration GPHCON to UART
  36.     rGPHCON &= ~(0xf<<4) ;
  37.     rGPHCON |= 0xa<<4 ;
  38.     //rGPHCON = 0x00faaa;
  39.     //rGPHUP = 0x7ff ;
  40.     //configuration UART0 communication register
  41.     //8-bits,1 stop bit, no parity
  42.     rULCON0 = 0x03 ;
  43.     rUCON0 = 0x05 ;
  44.     //configuration UART baudrate
  45.     rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;
  46.     //clean interrupt bit
  47.     rSUBSRCPND |= 0x3 ;
  48.     rSRCPND |= 1<<28 ;
  49.     rINTPND |= 1<<28 ;

  50.     //open UART interrupt
  51.     rINTSUBMSK &= ~(0x3) ;
  52.     rINTMSK &= ~(0x1<<28) ;    
  53. }

  54. void UART_send_byte(int Tx_data)
  55. {
  56.     //wait Tx empty
  57.     while(!(rUTRSTAT0&0x2)) ;
  58.     
  59.     rUTXH0 = Tx_data ;
  60. }

  61. void UART_receive_byte(void)
  62. {
  63.     char temp ;
  64.     //wait RX ready
  65.     while(!(rUTRSTAT0&0x1)) ;
  66.     
  67.     temp = rURXH0 ;
  68.     UART_send_byte(temp) ;
  69. }
  70. /*******************************************
  71. 中断处理函数
  72. 置1清除中断,注意顺序,先子中断后父中断
  73. 点亮led灯
  74. ********************************************/
  75. void __irq UART0_interrupt(void)
  76. {
  77.     rGPBDAT &= ~(0xf<<5) ;
  78.     //clean interrupt bit
  79.     rSUBSRCPND |= 0x3 ;
  80.     rSRCPND |= 1<<28 ;
  81.     rINTPND |= 1<<28 ;
  82.     //lighten led
  83.     rGPBDAT &= ~(0xf<<5) ;
  84.     UART_receive_byte();
  85. }
  86. /*******************************
  87. void UART_send_string(char *str)
  88. {
  89.     while(*str)
  90.     {
  91.         //delay(200) ;
  92.         UART_send_byte(*str) ;
  93.         str++ ;
  94.     }
  95. }
  96. *******************************/

  97. /*******************************************************************
  98. 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
  99. 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
  100. 分频比,确定好PCLK时钟。
  101. ********************************************************************/
  102. int Main(void)
  103. {
  104.     MMU_Init();
  105.     ChangeMPllValue(127,2,1);        //405MHZ
  106.     ChangeClockDivider(13,12); //1:3:6    
  107.     UART_int_init() ;
  108.     while(1)
  109.     {
  110.         pISR_UART0 = (U32)UART0_interrupt ;
  111.     }
  112.     return 0 ;
  113. }

阅读(6524) | 评论(3) | 转发(3) |
给主人留下些什么吧!~~

慕容宇月2019-06-13 20:45:28

非常感谢,很有帮助

慕容宇月2019-06-13 20:45:19

非常感谢,很有帮助

yanzi_1262011-04-18 20:43:26

刚好正在弄这个,对我很有帮组,非常感谢!