裸机系列——2440串口通信2程序代码
2011-04-04 21:26
253 查看
2011-04-04
关于一些串口通信的知识已经在上一篇文章中做了总结,这里主要讲程序的问题。
首先是直接通信,即不使用FIFO和中断的通信
代码
代码写的有点乱,开始没有主要风格。
下面的是没有FIFO的中断代码
最后的是使用FIFO的中断代码,一般发送没必要使用中断,我只使用了接受中断,中断处理也很简单
主要是熟悉串口通信原理。
代码如下
最后总结几句关于这次的串口通信程序,引用赵老师的。
1.
对于
s3c2440
来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;
2.
在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;
3.
由于
UART
中断涉及到
SUBSRCPND
寄存器,因此在中断处理程序中不仅要清
SRCPND
寄存器,还要清
SUBSRCPND
寄存器,它们的顺序一定是先清
SUBSRCPND
寄存器,再清
SRCPND
寄存器,否则就会引起一个中断两次响应的问题。因为是否中断由
SRCPND
寄存器决定,而
SRCPND
寄存器的相关状态位由
SUBSRCPND
寄存器决定,如果先清
SRCPND
寄存器,而还没有清
SUBSRCPND
寄存器的话,
SRCPND
寄存器的相关位还是会被置
1
,而一旦被置
1
,则一定还会引起中断
4.使用FIFO时相应的状态寄存器应该使用UFSTAT FIFO状态寄存器来查看FIFO中的数据,不用FIFO是直接查看接收发送寄存器UTRSTAT。21:30:00
关于一些串口通信的知识已经在上一篇文章中做了总结,这里主要讲程序的问题。
首先是直接通信,即不使用FIFO和中断的通信
代码
#define GLOBAL_CLK 1 #include <stdlib.h> #include <string.h> #include "def.h" #include "option.h" #include "2440addr.h" #include "2440lib.h" #include "2440slib.h" #include "mmu.h" #include "profile.h" #include "memtest.h" #define baud 115200 void led_port_init() { rGPBCON &= ~(0xff<<10) ; rGPBCON |= 0x55<<10 ; //rGPBCON = temp ; } void delay(int times) { int i = 1000 ; while(times--) { for(; i>0; --i) ; } } //set FIFO model ,no interrupt void UART_FIFO_init() { //set IO port GPHCON Rx0 Tx0 rGPHCON &= ~(0xf<<4) ; rGPHCON |= 0xa<<4 ; rGPHUP = 0x0 ; rULCON0 = 0x03 ; //8-bits,1 stop bit, no parity rUCON0 = 0x05 ; rUFCON0 = 0x00 ; rUMCON0 = 0x00 ; rUBRDIV0= (int)(PCLK/baud/16) -1 ; } void UART_send_byte(int Tx_data) { while(!(rUTRSTAT0&0x2)) ; if(Tx_data =='/n') { delay(500) ; rUTXH0 = '/n' ; } else { delay(500) ; rUTXH0 = Tx_data ; } } void UART_send_string(char *str) { while(*str) { delay(200) ; UART_send_byte(*str) ; str++ ; } } char UART_receive_byte(void) { //rGPBDAT &= ~(0xf<<5) ; while(!(rUTRSTAT0&0x1)) ; rGPBDAT &= ~(0xf<<5) ; return rURXH0 ; } void UART_receive(char *string) { char ch ; while(1) { if((ch=UART_receive_byte())=='/r') { UART_send_byte('/n'): } else { UART_send_byte(ch) ; } } } int Main(void) { char receive_buffer[80] ; //char send_buffer[] = "UART0 is OK!" ; ChangeClockDivider(13,12); //1:3:6 ChangeMPllValue(127,2,1); //405MHZ led_port_init() ; UART_FIFO_init() ; //UART_send(send_buffer) ; UART_send_string(" /n /n Please input a string: /n") ; delay(500) ; while(1) { UART_receive(receive_buffer) ; //delay(500) ; //UART_send_string(receive_buffer) ; //delay(500) ; } }
代码写的有点乱,开始没有主要风格。
下面的是没有FIFO的中断代码
#define GLOBAL_CLK 1 #include <stdlib.h> #include <string.h> #include "def.h" #include "option.h" #include "2440addr.h" #include "2440lib.h" #include "2440slib.h" #include "mmu.h" #include "profile.h" #include "memtest.h" #define baudrate 115200 /********************************** void delay(int times) { int i = 1000 ; while(times--) { for(; i>0; --i) ; } } ************************************/ /*********************************** UART_int初始化led IO端口GPBCON5-8 初始化GPBHCON为串口通信 配置串口通信寄存器 配置中断寄存器 ************************************/ void UART_int_init(void) { //configuration LED IO port rGPBCON &= ~(0xff<<10) ; rGPBCON |= 0x55<<10 ; //configuration GPHCON to UART rGPHCON &= ~(0xf<<4) ; rGPHCON |= 0xa<<4 ; //rGPHCON = 0x00faaa; //rGPHUP = 0x7ff ; //configuration UART0 communication register //8-bits,1 stop bit, no parity rULCON0 = 0x03 ; rUCON0 = 0x05 ; //configuration UART baudrate rUBRDIV0= (int)(PCLK/baudrate/16) -1 ; //clean interrupt bit rSUBSRCPND |= 0x3 ; rSRCPND |= 1<<28 ; rINTPND |= 1<<28 ; //open UART interrupt rINTSUBMSK &= ~(0x3) ; rINTMSK &= ~(0x1<<28) ; } void UART_send_byte(int Tx_data) { //wait Tx empty while(!(rUTRSTAT0&0x2)) ; rUTXH0 = Tx_data ; } void UART_receive_byte(void) { char temp ; //wait RX ready while(!(rUTRSTAT0&0x1)) ; temp = rURXH0 ; UART_send_byte(temp) ; } /******************************************* 中断处理函数 置1清除中断,注意顺序,先子中断后父中断 点亮led灯 ********************************************/ void __irq UART0_interrupt(void) { rGPBDAT &= ~(0xf<<5) ; //clean interrupt bit rSUBSRCPND |= 0x3 ; rSRCPND |= 1<<28 ; rINTPND |= 1<<28 ; //lighten led rGPBDAT &= ~(0xf<<5) ; UART_receive_byte(); } /******************************* void UART_send_string(char *str) { while(*str) { //delay(200) ; UART_send_byte(*str) ; str++ ; } } *******************************/ /******************************************************************* 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的 分频比,确定好PCLK时钟。 ********************************************************************/ int Main(void) { MMU_Init(); ChangeMPllValue(127,2,1); //405MHZ ChangeClockDivider(13,12); //1:3:6 UART_int_init() ; while(1) { pISR_UART0 = (U32)UART0_interrupt ; } return 0 ; }
最后的是使用FIFO的中断代码,一般发送没必要使用中断,我只使用了接受中断,中断处理也很简单
主要是熟悉串口通信原理。
代码如下
#define GLOBAL_CLK 1 #include <stdlib.h> #include <string.h> #include "def.h" #include "option.h" #include "2440addr.h" #include "2440lib.h" #include "2440slib.h" #include "mmu.h" #include "profile.h" #include "memtest.h" #define baudrate 115200 /********************************** void delay(int times) { int i = 1000 ; while(times--) { for(; i>0; --i) ; } } ************************************/ /*********************************** UART_int初始化led IO端口GPBCON5-8 初始化GPBHCON为串口通信 配置串口通信寄存器FIFOt通信 配置中断寄存器 ************************************/ void UART_int_init(void) { //configuration LED IO port rGPBCON &= ~(0xff<<10) ; rGPBCON |= 0x55<<10 ; //configuration GPHCON to UART rGPHCON &= ~(0xf<<4) ; rGPHCON |= 0xa<<4 ; //configuration UART0 communication register //8-bits,1 stop bit, no parity rULCON0 = 0x03 ; rUCON0 = 0x05 ; rUFCON0 = 0x3f ; //configuration UART baudrate rUBRDIV0= (int)(PCLK/baudrate/16) -1 ; //clean interrupt bit rSUBSRCPND |= 0x1 ; rSRCPND |= 1<<28 ; rINTPND |= 1<<28 ; //open UART interrupt rINTSUBMSK &= ~(0x1) ; rINTMSK &= ~(0x1<<28) ; } void UART_send_byte(int Tx_data) { //wait Tx empty while(!(rUTRSTAT0&0x2)) ; rUTXH0 = Tx_data ; } void UART_receive(void) { char temp ; //wait RX ready while((rUFSTAT0&0x3F)) { temp = rURXH0 ; UART_send_byte(temp) ; } } /******************************************* 中断处理函数 置1清除中断,注意顺序,先子中断后父中断 点亮led灯 ********************************************/ void __irq UART0_interrupt(void) { rGPBDAT &= ~(0xf<<5) ; //clean interrupt bit rSUBSRCPND |= 0x1 ; rSRCPND |= 1<<28 ; rINTPND |= 1<<28 ; //lighten led rGPBDAT &= ~(0xf<<5) ; UART_receive(); } /******************************* void UART_send_string(char *str) { while(*str) { //delay(200) ; UART_send_byte(*str) ; str++ ; } } *******************************/ /******************************************************************* 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的 分频比,确定好PCLK时钟。 ********************************************************************/ int Main(void) { MMU_Init(); ChangeMPllValue(127,2,1); //405MHZ ChangeClockDivider(13,12); //1:3:6 UART_int_init() ; while(1) { pISR_UART0 = (U32)UART0_interrupt ; } return 0 ; }
最后总结几句关于这次的串口通信程序,引用赵老师的。
1.
对于
s3c2440
来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;
2.
在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;
3.
由于
UART
中断涉及到
SUBSRCPND
寄存器,因此在中断处理程序中不仅要清
SRCPND
寄存器,还要清
SUBSRCPND
寄存器,它们的顺序一定是先清
SUBSRCPND
寄存器,再清
SRCPND
寄存器,否则就会引起一个中断两次响应的问题。因为是否中断由
SRCPND
寄存器决定,而
SRCPND
寄存器的相关状态位由
SUBSRCPND
寄存器决定,如果先清
SRCPND
寄存器,而还没有清
SUBSRCPND
寄存器的话,
SRCPND
寄存器的相关位还是会被置
1
,而一旦被置
1
,则一定还会引起中断
4.使用FIFO时相应的状态寄存器应该使用UFSTAT FIFO状态寄存器来查看FIFO中的数据,不用FIFO是直接查看接收发送寄存器UTRSTAT。21:30:00
相关文章推荐
- S3C2440之裸机程序烧录(eop+Jlink)
- 存储过程系列之存储过程sql数据库调用和程序代码调用
- S3C2416裸机开发系列二_汇编入门代码以及sd卡启动
- Android 4.X系列の界面设计中退出Android程序的代码
- C语言系列(二):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序
- 五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
- 2440裸板程序之代码重定位
- C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序
- 2440裸机启动代码分析
- Mini 2440 LED、按键和蜂鸣器裸机测试程序(C语言)
- STC15F2K60S2/STC15系列读取MPU6050陀螺仪角度加速度串口显示程序代码
- 裸机系列——2440时钟
- tiny4412 裸机程序 七、重定位代码到DRAM【转】
- Eclipse开发调试ARM裸机程序(四)赤裸裸的代码拷贝
- 关于从NAND Flash启动的问题,2440 启动问题 , 拷贝4k程序 ,启动代码分析
- S3C2416裸机开发系列九_GCC启动代码工程应用实例
- S5PV210系列(裸机九)之 串口通信
- Zenq系列FPGA双核ARM裸机异步程序实现
- C语言系列(四):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序
- C语言系列(一):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序