119364|11

152

帖子

0

TA的资源

裸片初长成(初级)

楼主
 

【EEWORLD】救火车和你一起学ARM系列活动之七 [复制链接]

----串行口实验
这回我们来研究一下一个重要的片内外设串行口。我相信大家都知道口串行口吧,我就不过多介绍它了。闲话少说,我们开始。
LPC2103有两个串行口。UART0和UART1,下面我们以UART0为例,介绍串行口。
管脚连接设置
需要设置IO口连接模块PINSEL0,设成连接到UART0. 请参考活动六的介绍。
PINSEL=0x05;
串行口波特率的设置
LPC2103具有内置的波特率发生器。
我们需要设置波特率分频寄存器(共16位)。U0DLM是高8位,U0DLL是低8位。
分频值 =  Fpclk/16/波特率
Fpclk:我们在活动3中介绍过。我们的晶振是11.0592经过PLL的6倍频和VPB的4分频,供给片内外设的时钟是11.0592M*6/4=16.5888MHz
我们计算9600波特率的分频值 = 16588800/16/9600 =108 =0x006c
计算结果
U0DLM=0x00;
U0DLL=0x6c;

注:设置分频寄存器时还要将U0LCR的第7位置1
其他重要寄存器介绍
U0LCR:UART0控制寄存器

UOLCR

功能

描述

复位值

1:0

子长度选择

00:5位字符长度
01:6位字符长度
10:7位字符长度
11:8位字符长度
0

2

停止位选择

0: 1个停止位
1:2个停止位(如果U0LCR[1:0]=00则为1.5)
0

3

奇偶使能

0:禁止奇偶产生和校验
1:使能奇偶产生和校验
0

5:4

奇偶选择

00:奇数
01:偶数
10:强制为1
11:强制为0
0

6

间隔控制

0:禁止间隔发送
1:使能间隔发送
当U0LCR的bit6为1时,输出引脚UART0 TxD强制为逻辑0
0

7

除数锁存访问位

0:禁止访问除数锁存寄存器
1:使能访问除数锁存寄存器
0



U0IER 中断使能寄存器 = 0x07;
U0IER
功能
描述
复位值
第0位
RBR中断使能
接收到数据或接收超时。0:禁止  1:使能
0
第1位
THRE中断使能
发送缓冲为空
0
第2位
Rx线状态中断使能

0

U0THR 发送寄存器。把需要向外发的数据直接赋值给它。
U0RBR 接收寄存器。从这个寄存器中读取接收到的数据。
U0IIR 中断标识寄存器
U0IIR[3:0]
优先级
中断类型
中断源
中断复位
   0110
最高
Rx线状态/错误
OE,PE,FE,或BI
U0LSR读操作
   0100
第二
Rx数据可用
Rx数据可用或FIFO模式下(U0FCR0=1)到达触发点
U0RBR读或UART0 FIFO低于触发值
   1100
第二
字符超时指示
Rx FIFO包含至少1个字符并且在一段时间内无字符输入或移出
U0RBR读操作
   0010
第三
THRE
THRE  发送缓冲为空中断
U0IIR读或写操作
在定时器中断函数中,需要读取此寄存器,用来区分中断的来源。

程序例子
我们采用中断方式,来实现串行口的收发动作。周立功的书中已给介绍了查询方式的收发,我们这里不再详述。中断方式的好处是占用的CPU时间少,CPU不必“等”着串行口的数据发完,而是利用收、发产生的中断再实现数据装入和读回。
源文件main.c和subuart0.c请到 www.qm999.cn 下载
//初始化UART0  中断方式
void Init_uart0()
{

    U0LCR = 0x83; //使能访问除数寄存器     
    U0DLM = 0x00; //115200时为6   9600时为0x006c
    U0DLL = 0x6c;
    U0LCR = 0x03; //禁止访问除数寄存器      
    U0IER = 0x03; //允许接收数据可用中断[第0位]和发送缓冲为空中断[第1位]
    //以下是中断设置 设置为中断通道0
    VICIntSelect = 0x00000000;
    VICVectCntl0 = 0x26; //第5位置1:向量使能,[4:0]中断源序号
    VICVectAddr0 = (unsigned long)&IRQ_UART_0;
    VICIntEnable = 0x00000040;   
    PINSEL0 |= 0x00000005;
  }
//以下以串行口中断方式程序
// USART Receiver buffer
#define RX_BUFFER_SIZE_0 100
unsigned char rx_buffer_0[RX_BUFFER_SIZE_0];
unsigned char rx_wr_index_0=0,rx_rd_index_0=0,rx_counter_0=0;

// USART Transmitter buffer
#define TX_BUFFER_SIZE_0 100
unsigned char tx_buffer_0[TX_BUFFER_SIZE_0];
unsigned char tx_wr_index_0=0,tx_rd_index_0=0,tx_counter_0=0;

// USART Receiver interrupt service routine
__irq __arm void IRQ_UART_0(void)
{
    unsigned char data;


    switch(U0IIR&0x0e)
    {
        //case 0x06://011:1.接收线状态(RLS)
        //    data = U0LSR;
        //    break;
        case 0x04://010:2a.接收数据可用(RDA)
            data = U0RBR;
            rx_buffer_0[rx_wr_index_0]=data;
            if (++rx_wr_index_0 == RX_BUFFER_SIZE_0) rx_wr_index_0=0;
            if (++rx_counter_0 == RX_BUFFER_SIZE_0) rx_counter_0=0;        
            break;
        //case 0x0c://110:2b.字符超时指示(CTI)
        //    data = U0RBR;
        //    break;
        case 0x02://001:3.THRE中断  发送缓冲为空中断
            if (tx_counter_0)
            {//1次写入FIFO最多16个字节
                --tx_counter_0;
                U0THR = tx_buffer_0[tx_rd_index_0];
                if (++tx_rd_index_0 == TX_BUFFER_SIZE_0) tx_rd_index_0=0;
            }   
            break;
        default:
            break;     
    }
    VICVectAddr = 0x00;
}

//读取一个字节
unsigned char getchar_0(void)
{
unsigned char data;
while (rx_counter_0==0);
data=rx_buffer_0[rx_rd_index_0];
if (++rx_rd_index_0 == RX_BUFFER_SIZE_0) rx_rd_index_0=0;
VICIntEnable &= 0xffffffbf;
--rx_counter_0;
VICIntEnable |= 0x00000040;
return(data);
}

//发送一个字节
void putchar_0(unsigned char data)
{
    while (tx_counter_0 == TX_BUFFER_SIZE_0);
    VICIntEnable &= 0xffffffbf;
    if (tx_counter_0 || ((U0LSR&0x40)==0))
    {
        tx_buffer_0[tx_wr_index_0]=data;
        if (++tx_wr_index_0 == TX_BUFFER_SIZE_0) tx_wr_index_0=0;
        ++tx_counter_0;
    }
    else   
    {
        U0THR = data;
    }
    VICIntEnable |= 0x00000040;
}
//主程序 功能是将接收到的数字,加1以后回发。
int main (void)
{
    。。。。。。//其他程序略
    Init_uart0();
    while(1)
    {
          if (rx_counter_0>0)        
          {
              while(rx_counter_0>0) putchar_0(getchar_0()+1);//加1 ,回发        
          }
    }


}


硬件原理图如下:

实验板硬件图如下所示:

正面


背面



实验效果演示:
用串口调试工具发一串数,能够看到数据加1后,回发。

可以看到实上面的实验效果。电脑发出的数字,被加1,回发了回来。

我们在这次实验中启用了新制作的USB仿真器。下面是效果图。


下一次我们准备做IIC接口实验,请大家准备一个3.3V的24WC02或兼容芯片。
此帖出自单片机论坛

最新回复

不错。谢谢楼主  详情 回复 发表于 2010-11-1 15:04
点赞 关注
个人签名我是有火救火,无火灌水的救火车
救火车单片机工作室
http://www.qm999.cn
 

回复
举报

33

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
等了这一讲好久了,终于等到了!
此帖出自单片机论坛
 
 

回复

2万

帖子

74

TA的资源

管理员

板凳
 

回复 沙发 rpybx 的帖子

请随时关注,大家随时讨论啊
此帖出自单片机论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

4
 
写的很好啊,清晰易懂,什么时候把STM的学习也介绍一下呢,呵呵
此帖出自单片机论坛
 
 
 

回复

16

帖子

0

TA的资源

一粒金砂(中级)

5
 
学习一下LPC2103的串口通信实验,跟8位的差不多吧!
此帖出自单片机论坛
 
 
 

回复

53

帖子

0

TA的资源

纯净的硅(初级)

6
 
不错,不懂,也看看....
此帖出自单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

7
 
感谢版主分享,好好学习一下,现在正在学习ARM。
此帖出自单片机论坛
 
 
 

回复

87

帖子

0

TA的资源

纯净的硅(中级)

8
 

救火车和你一起学ARM系列活动之七

此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

9
 

很好啊

楼主的帖子 是在 是很好啊
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

10
 

很好啊

很好
此帖出自单片机论坛
 
 
 

回复

30

帖子

0

TA的资源

一粒金砂(初级)

11
 
现在正在学习!谢谢楼主!
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

12
 

不错。谢谢楼主

此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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