完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 MouseesuoM 于 2015-2-4 17:41 编辑 我记得在GPIO流水灯的时候,是用宏自己定义的寄存器(#define (*(volatile unsigned *) 寄存器的地址)),那个程序是可行的,但是在串口实验中用自己定义的寄存器来进行操作时,每当给UART0_C2赋值的时候,程序就跳转到启动代码(.S文件)中的 HardFault_Handler 自己也琢磨了好几天 始终不明白为什么(我会把这个代码上传希望高手能解答一下)。所以也就放弃了自己定义寄存器的想法。而是转用别人定义的寄存器来操作的。 下面进入主题,当然自己在编写代码过程中也遇到很多问题,希望各位好友知道的能给解答一下。 (一) 其实KL25芯片许多引脚都可以用来当做串口的输入输出:PA1 PA2,PA14 PA15,PD6 PD7 ,PE20 PE21,PE16 PE17,那么你怎么知道这些引脚可以当做串口来使用?而且你是怎么选择使用哪一对来进行编程的? 引脚的复用功能(所谓复用就是除了普通的GPIO的输入输出功能还有额外的功能,比如说今天的串口的发送接收引脚,比如说的用来当做SPI通讯的接收、输出、时钟、片选引脚等),这些功能需要查看数据手册的 10.3.1节 KL25信号复用和引脚列表,那么这些东西就不难知道了。那具体实际需要编程哪个引脚呢?那么就要看原理图了, 从原理图上不难发现是用的PA1 和PA2,自己当时还很傻的用PE20 和P21 来进行编程,真是感觉傻到家了。 当然如果要使用PA1 PA2 就是要对着两个引脚初始化,那么要特别注意,在PCR寄存器(引脚控制寄存器中),这两个引脚的控制寄存器的MUX位要设置为010,因为用的是这两个引脚的第二复用功能,所以是010,以此类推,如果用的是第五复用功能(一共是七个),那么就是101了。 (二) 下来,就要确定该怎么编程了,其实我们不难发现,一般串口就那些设置,波特率、起始位、数据位、奇偶校验、流控制等等,一般来说对于我们就足够了。 我们要的是串口0,关于串口0的介绍在数据手册的第39章。 下来卡数据手册: 1、首先第一个寄存器是设置波特率的,他是由两个寄存器(UART0_BDH UART0_BLH)确定的,具体组成是UART0_BDH 的低5位和UART0_BLH全部8位 共13位构成。(看到这里我也是醉了,cotex-m0到底是多少位的芯片,怎么还能出来8位宽的寄存器了?) 接着往下说,那么不难发现波特率的计算公式 UART 波特率=UART 模块时钟/((OSR+1)*BR (1)那么第一个问题来了,UART模块时钟是多少? 在数据手册 第五章中不难发现 UART0的时钟分配 我们不难发现UART0的时钟源设置由SIM_SOPT2寄存器控制的,我们找到这个寄存器(具体的寄存器大家还是去看数据手册,这里我就不给贴出来),其中关于UART0的时钟源选择的控制位是D27:D26 D27~26(UART0SRC)—UART0 时钟源选择。 为 UART0 发送和接收时钟选择时钟源。00 禁用时钟; 01 MCGFLLCLK 时钟或 MCGPLLCLK/2 时钟; 10 OSCERCLK 时钟; 11MCGIRCLK 时钟。 在本次实验中,我们选择MCGPLL/2,也就是说[D27:D26]为01。 同时该寄存器的D16位也要设置为1。通俗点讲就是到底用哪个时钟为外设提供时钟。这里我们用MCGPLL/2,自然D16要写入1(发现中文数据对这一位的叙述正好写反了。) 那么MCGPLL/2=?,我们在startup_MKL25Z4.s启动代码中不难发现: LDRR0,=SysytemInit 这行代码,具体是什么意思我不清楚还请高人指教,但是大概意思是就是在系复位后,会调用SystemInit函数,那么SystemInit函数在哪呢?-----在system_MKL25Z4.c中,在这个C文件中可以找到SystemInit函数,具体我就不贴出来,这段函数主要是对系统等一些时钟的设置大家想了解可以自己看。
在system_MKL25Z4.c中CLOCK_SETUP选择的是1, 所以调用SystemInit函数后, MCGIRCLK(4000Khz),MCGPLL (48000Khz) BUSCLK(24000khz)。【这里关于时钟的问题,理解是不正确的大家可以参考一下12楼】 所以UART0的模块配置完后是时钟24Mhz。(其实就是BusClock)。 (2)OSR的确定 OSR是由UART0控制寄存器4中的[D4:D0]来确定的,默认的复位值是01111 页就是OSR=16。 在本次实验中,波特率115200,所以带入上述的公式,不难确定BR=13(00000 00001101),所以在UART0_BDH的低5位全部写0,而UART0_BLH写入 0x0D即可。 关于UART0_BDH的D5是停止位的选择,我们设置为1位(默认即可),其余两个是关于中断机制的串口通讯我们不用管也是默认。 2、UART0_C1(串口控制寄存器1) 这里我们只需要处理标记的位就可以(具体内容还是看数据手册吧): LOOPS:0--采用不同的引脚正常操作UART_TX、UART_RX M :数据位的选择 0对应的是8位模式 PE :奇偶校验 0 不使能 PT :是奇校验还是偶校验(这里不用管 默认就可以了) 3、UART0_C2(串口控制寄存器2)
TE:发送器使能位 RE:接收器使能位 其余位默认即可,不用去设置。 这里在多讲一点,所有关于波特率的设置,控制寄存器的操作设置,必须发送 接收器禁止才能设置,一旦使能就不要在操作这些寄存器了。 4、UART0_S1(UART0状态寄存器) TDRE:复位值 是 1,表示发送缓冲器是空的,当向写 UART 数据寄存器( UART_D),其值变为0 表示发送缓冲器满。 这里我个人认为 TDRE是不会自动置1的,所以还需要在代码中自己操作寄存器实现置1(本人经过试验发现的,如有不对请指正)。 TC:发送完成标志。 1:发送完成。写 UART 数据寄存器( UART_D)来发送新的 数据,TC 被自动清除变为0。RDRF:RDRF=0, 接收数据寄存器空; RDRF=1,接收数据寄存器满。 其余位 默认就可以。 5、UART0_D(UART数据寄存器) 这个没什么好说的了,如果要发送数据,需要向该寄存器写入值。如果接受数据,数据会保存在该寄存器中。在读写该寄存器时,某些寄存器位会自动置位或者清除,这里我就不说了,大家看数据手册就可以。 Polling机制的串口通讯差不多就这些操作就够了。所谓Polling机制就是轮训的机制,不断的查询。 还有建立工程时,用的别人实现的寄存器(好像是周立功用官方库实现的),下载的话大家可以根据这个帖子https://bbs.elecfans.com/forum.php?mod=viewthread&tid=463417,自己随便找个例子修改修改就可了。具体的操作我会在发个帖子。 最后上传下自己的代码
UART2.rar
(457.8 KB, 下载次数: 116
)
评分
|
||
相关推荐
21 个讨论
|
||
只有小组成员才能发言,加入小组>>
1932个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36415 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4811 浏览 1 评论
6100 浏览 1 评论
6813 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4244 浏览 0 评论
641浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
638浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
639浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
725浏览 2评论
836浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 05:58 , Processed in 1.450723 second(s), Total 90, Slave 68 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号