嵌入式课程设计.docx

上传人:小飞机 文档编号:3480984 上传时间:2023-03-13 格式:DOCX 页数:18 大小:44.63KB
返回 下载 相关 举报
嵌入式课程设计.docx_第1页
第1页 / 共18页
嵌入式课程设计.docx_第2页
第2页 / 共18页
嵌入式课程设计.docx_第3页
第3页 / 共18页
嵌入式课程设计.docx_第4页
第4页 / 共18页
嵌入式课程设计.docx_第5页
第5页 / 共18页
亲,该文档总共18页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《嵌入式课程设计.docx》由会员分享,可在线阅读,更多相关《嵌入式课程设计.docx(18页珍藏版)》请在三一办公上搜索。

1、嵌入式课程设计嵌入式系统课程设计 重力加速度模块 组长: * 组员: * 目 录 第一章 概 述 . 2 11 课程背景 . 2 12 实验选材 . 3 13 实验内容 . 4 14 KL25介绍 . 4 第三章 模块设计 . 8 21 流程图 . 8 22 代码解析 . 8 23 问题及解决方法 . 18 第三章 小 结 . 21 - 1 - 第一章 概 述 1.1 课程背景 嵌入式系统是一种“完全嵌入受控器件内部,为特定应用而设计的专用计算机系统”,根据英国电气工程师协会的定义,嵌入式系统为控制、监视或辅助设备、机器或用于工厂运作的设备。与个人计算机这样的通用计算机系统不同,嵌入式系统通常

2、执行的是带有特定要求的预先定义的任务。由于嵌入式系统只针对一项特殊的任务,设计人员能够对它进行优化,减小尺寸降低成本。嵌入式系统通常进行大量生产,所以单个的成本节约,能够随着产量进行成百上千的放大。 嵌入式系统是用来控制或者监视机器、装置、工厂等大规模设备的系统。国内普遍认同的嵌入式系统定义为:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。通常,嵌入式系统是一个控制程序存储在ROM中的嵌入式处理器控制板。事实上,所有带有数字接口的设备,如手表、微波炉、录像机、汽车等,都使用嵌入式系统,有些嵌入式系统还包含操作系统,但大多

3、数嵌入式系统都是由单个程序实现整个控制逻辑。 嵌入式系统的核心是由一个或几个预先编程好以用来执行少数几项任务的微处理器或者单片机组成。与通用计算机能够运行用户选择的软件不同,嵌入式系统上的软件通常是暂时不变的;所以经常称为“固件”。 目前,嵌入式系统是近年来发展很快的计算机方面的学科方向,并迅速渗透到控制、自动化、仪器仪表等学科。嵌入式方向包括了软硬件协同设计、嵌入式体系结构、实时操作系统、嵌入式产品设计等方面的知识,大于当代大学生,更需要掌握嵌入式系统设计的典型开发工具和开发核心技术。 飞思卡尔的Kinetis L系列MCU是业内首款基于ARM Cortex-M0+内核的MCU,具有超低功耗

4、、应用设计方便、扩展性好、系列品种齐全等特点。KL系列MCU面向家用电器、便携式医疗系统、智能电表、照明、电源、电机控制及工业控制等,对稳定性、功耗、成本和易用性等方面有较严格要求的市场。对于我们学习应用嵌入式技术有着重大作用。 1.2 实验选材 1. 开发板 KL25 FRDM-KL25Z是一款超低成本开发平台,面向基于 - 2 - ARM Cortex-M0+处理器的Kinetis L系列 KL1x (KL14/15)和KL2x (KL24/25) MCU。该硬件的特性包括可轻 访问MCU I/O,配备电池,低功率运行,采用可搭配扩展板 标准规格,以及用于闪存编程和运行控制的内置调试接口。

5、 FRDM-KL25Z受到众多飞思卡尔和第三方开发软件的支持。 松的2. 键 盘 4 x 4矩阵按键,16个按键,8个I/O 矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线, 4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉 点上,设置一个按键。这样键盘中按键的个数是44个。这种 行列式键盘结构能够有效地提高单片机系统中I/O口利用率。 3. 显示器 液晶显示器模块 1.3 实验内容 - 3 - 1. 三色灯 2. 键盘输入输出 3. 传感器 1.4 KL25介绍 1.4.1 综述 FRDM-KL25Z可以用来评估KL1和KL2 Kinetis L系列设备。处理器为飞思卡尔的KL

6、25Z128VLK,该处理器的主频为48M HZ,包含128K的flash,一个全速USB控制器和大量模拟和数字外设。FRDM-KL25Z可兼容Arduino扩展板,提供众多的扩展板支持。FRDM-KL25Z是第一款支持飞思卡尔的开放式嵌入式串行和调试适配器标准OpenSDA的硬件平台。这为FRDM-KL25Z提供了多种形式的串行通信,flash编程和调试运行的方式。板载的硬件接口包括一个RGB LED,一个三轴加速度传感器和一个数字电容触摸滑动。 1.4.2 主要特点 1. Processor Expert中支持软件包括:单机或集成的IDE、MQX Lite RTOS和生态系统合作伙伴; 2

7、. OpenSDA调试接口; 3. P&E多连接的运行控制调试界面; 4. 开发套件的外形和硬件与Arduin和Arduino开发套件兼容; 5. 可以快速、简单和方便地访问MCU的I/O资源; 6. 大容量Flash编程接口; 7. 开源数据记录应用; 8. 多种供电电源可选:USB供电、钮扣电池或3.3V/5V电源供电。 1.4.3 硬件资源 1. 板载MCU型号MKL25Z128VLK4:主频最高48MHz,128kB 的Flash,支持USB功能; 2. 支持TSI; 3. 预留SPI Flash接口; 4. 板载调试下载器; 5. 板载三轴加速传感器:MMA8451Q; 6. 板载R

8、GB LED。 1.4.4 套接口说明 1. KL25ZUSB接口:此接口为板载MCU 的USB接口,可调试usb_device等与USB相关的例程,芯 片本身支持usb_host功能,但FRDM-KL25Z开发套件本身并 不支持,需要用户自行设计。 - 4 - 2. OpenSDA接口:此接口为调试、下载或串行通信接口,具体 的接口功能和OpenSDA内部板级支持包有关,官方出厂默认 为大容量存储设备闪存编程接口,即无需安装工具,开发套件 会虚拟成一个USB设备,用户仅需将预编译的例程拷贝到优盘 设备即可完成程序烧写,这样可以方便用户快速的评估开发套 件性能。 3. Reset按键:此按键为

9、MCU的复位按键。 4. J1、J2、J9和J10接口:此接口为板载MCU电源及I/O等的 输入/输出接口,其中J9的16管脚直接连接LDO的输入管脚, 可支持5V-9V电压输入。 5. 电容式滑条:开发套件的顶端带有一个电容式滑条,用户可以 使用官方的TSS库对开发套件的电容式滑条进行相关评估。 6. J8为板载OpenSDA芯片的JTAG接口:通过此接口可以为板 载OpenSDA芯片进行JTAG固件升级。 7. J6为SWD接口:此接口是板载OpenSDA的输出接口,它可 以对板载MCU进行程序下载及仿真等功能,也可输出为其它 MCU进行程序下载或在线仿真。 8. J11在开发套件背面通过

10、小刀或其它工具划开PCB导线即可断 开。 9. J3为OpenSDA的电源跳线:出厂默认为导通状态,若用户需 要禁能OpenSDA将J3断路即可。 10. J3在开发套件背面通过小刀或其它工具划开PCB导线即可断 开。 11. J4为板载MCU的电源跳线:出厂默认为导通状态,若用户需 要直接测量MCU的功耗只需将J4连线断开对MCU进行单独 供电并将电流表串联到电路即可完成功耗测量。 12. J4在开发套件背面通过小刀或其它工具划开PCB导线即可断 开。 13. J11为板载MCU与OpenSDA下载选择跳线:出厂默认为导 通状态,若需使用板载OpenSDA对板外MCU仿真或下载, 需将J11

11、断路。 - 5 - 第二章 模块设计 2.1 流程图 - 6 - 2.2 代码解析 2.2.1 头文件 hal_dev_mma8451.h #ifndef _HAL_DEV_MMA8451_ #define _HAL_DEV_MMA8451_ #include global.h void hal_dev_mma8451_init(void); u8 hal_dev_mma8451_read_reg(u8 addr); void hal_dev_mma8451_write_reg(u8 addr, u8 data); bool hal_dev_mma8451_test_reg_rw(void);

12、 void hal_dev_mma8451_test_function(void); #endif - 7 - hal_i2c.h #ifndef _HAL_I2C_ #define _HAL_I2C_ void hal_i2c_init(void); #endif hal_i2c_ex.h #ifndef _HAL_I2C_EX_ #define _HAL_I2C_EX_ void i2c_set_tx_mode(I2C_MemMapPtr p); void i2c_set_rx_mode(I2C_MemMapPtr p); void i2c_set_slave_mode(I2C_MemMa

13、pPtr p); void i2c_set_master_mode(I2C_MemMapPtr p); void i2c_give_nack(I2C_MemMapPtr p); void i2c_give_ack(I2C_MemMapPtr p); void i2c_repeated_start(I2C_MemMapPtr p); void i2c_write_byte(I2C_MemMapPtr p, byte data); byte i2c_read_byte(I2C_MemMapPtr p); void i2c_start(I2C_MemMapPtr p); void i2c_stop(

14、I2C_MemMapPtr p); bool i2c_wait(I2C_MemMapPtr p); bool i2c_get_ack(I2C_MemMapPtr p); void hal_i2c_init(void); #define I2C_READ 1 #define I2C_WRITE 0 #endif 2.2.2 详细代码 hal_dev_mma8451.c #include common.h #include global.h #include hal_i2c_ex.h #include lcd.h #define I2C_ADDR_MMA8451 (0x1d1) #define I

15、2C0_B I2C0_BASE_PTR /* This delay is very important, it may cause w-r operation failure. - 8 - The delay time is dependent on the current baudrate. It must be equal or longer than at least on clock of current baudrate. So, if you set to a higher baudrate, the loop value can be reduced from 4000 to 2

16、0, depending on your current baudrate. */ static void pause(void) int n; for(n=0; n4000; n+) asm(nop); u8 hal_dev_mma8451_read_reg(u8 addr) u8 result; / 将I2C模块配成主机发送模式,I2Cx_C1寄存器的MST和TX位置1 i2c_start(I2C0_B); / 写并呼叫从机地址0x1D i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_WRITE); / 等待呼叫的从机地址匹配 i2c_wait(

17、I2C0_B); / 查看是否收到Ack位 i2c_get_ack(I2C0_B); / I2C数据段需要访问的MM8451寄存器地址 i2c_write_byte(I2C0_B, addr); i2c_wait(I2C0_B); i2c_get_ack(I2C0_B); / 主机在发起一帧I2C起始信号 i2c_repeated_start(I2C0_B); / 读并呼叫从机地址 i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_READ); i2c_wait(I2C0_B); i2c_get_ack(I2C0_B); / I2C0模块设置成接收模式

18、 i2c_set_rx_mode(I2C0_B); / TXAK=1,准备收完下一字节数据后自动发送nack信号 i2c_give_nack(I2C0_B); / 启动接收下一字节数据 result = i2c_read_byte(I2C0_B); / 清除1字节传送完毕标 i2c_wait(I2C0_B); - 9 - i2c_stop(I2C0_B); / 读取I2C数据寄存器值,MMA8451被访问的寄存器值 result = i2c_read_byte(I2C0_B); / 至少等待一个当前波特率周期 pause; return result; void hal_dev_mma8451

19、_write_reg(u8 addr, u8 data) / 将I2C模块配置成主机发送模式 i2c_start(I2C0_B); / 写并呼叫从机地址 i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451|I2C_WRITE); / 等待呼叫的从机地址匹配 i2c_wait(I2C0_B); / 查看是否收到ACK位 i2c_get_ack(I2C0_B); / I2C数据段填写需要访问的MM8451寄存器地址 i2c_write_byte(I2C0_B, addr); i2c_wait(I2C0_B); i2c_get_ack(I2C0_B); / I2C数据段填

20、写需要对寄存器写入的值 i2c_write_byte(I2C0_B, data); i2c_wait(I2C0_B); i2c_get_ack(I2C0_B); i2c_stop(I2C0_B); pause; static void to_active_mode(void) u8 v; v = hal_dev_mma8451_read_reg(0x2a); hal_dev_mma8451_write_reg(0x2a,v|0x01); static void to_standby_mode(void) u8 v; v = hal_dev_mma8451_read_reg(0x2a); hal

21、_dev_mma8451_write_reg(0x2a,v&0x7e); - 10 - void hal_dev_mma8451_init(void) to_standby_mode; / 对重力加速度进行测试 bool hal_dev_mma8451_test_reg_rw(void) u8 d; d = hal_dev_mma8451_read_reg(0x2f); printf(d=%xn,d); hal_dev_mma8451_write_reg(0x2f,0xaa); d = hal_dev_mma8451_read_reg(0x2f); printf(d=%xn,d); hal_d

22、ev_mma8451_write_reg(0x2f,0x55); d = hal_dev_mma8451_read_reg(0x2f); printf(d=%xn,d); hal_dev_mma8451_write_reg(0x2f,0xff); d = hal_dev_mma8451_read_reg(0x2f); printf(d=%xn,d); hal_dev_mma8451_write_reg(0x2f,0x00); d = hal_dev_mma8451_read_reg(0x2f); printf(d=%xn,d); return 0; void hal_dev_mma8451_t

23、est_function(void) s16 resultx; s16 resulty; s16 resultz; / 激活MM8451模块 to_active_mode; / printf(X Y Zn); / 通过I2C读取8451的STATUS/F_STATUS状态寄存器 XYZ三轴是否有新值 if(hal_dev_mma8451_read_reg(0x00)&0xf) != 0) resultx = 0; resulty = 0; - 11 - resultz = 0; / 通过I2C读取8451的OUT_X_MSB和OUT_X_LSB结果寄存器拼出 X轴加速度值 resultx =

24、hal_dev_mma8451_read_reg(0x01)= 2; resulty = hal_dev_mma8451_read_reg(0x03)= 2; resultz = hal_dev_mma8451_read_reg(0x05)= 2; / 输出XYZ三轴的加速度值 if(resultx=0&resulty=0&resultz=0) LCDShow(x=0,y=0,z=0 ); if(resultx=0&resulty=0&resultz=0,y=0,z=0&resulty=0) LCDShow(x=0,y=0 ); if(resultx=0&resulty0&resultz=0,

25、y0,z0 ); if(resultx=0&resultz=0) LCDShow(x=0,z=0 ); if(resultx=0&resultz0) LCDShow(x=0,z0 ); if(resultx0&resulty=0) LCDShow(x0,y=0 ); if(resultx0&resulty0&resultz0) LCDShow(x0,y0,zC1 |= I2C_C1_TX_MASK; / 接收模式 void i2c_set_rx_mode(I2C_MemMapPtr p) p-C1 &= I2C_C1_TX_MASK; / 设置从机模式 void i2c_set_slave_m

26、ode(I2C_MemMapPtr p) p-C1 &= I2C_C1_MST_MASK; / 设置主机模式 void i2c_set_master_mode(I2C_MemMapPtr p) p-C1 |= I2C_C1_MST_MASK; / i2c general / 发送非应答信号 void i2c_give_nack(I2C_MemMapPtr p) p-C1 |= I2C_C1_TXAK_MASK; / 发送应答信号 void i2c_give_ack(I2C_MemMapPtr p) p-C1 &= I2C_C1_TXAK_MASK; / 重新开始信号 void i2c_repe

27、ated_start(I2C_MemMapPtr p) p-C1 |= 0x04; / 写字节 void i2c_write_byte(I2C_MemMapPtr p, byte data) p-D = data; / 读字节 byte i2c_read_byte(I2C_MemMapPtr p) - 13 - return p-D; / 开始信号 void i2c_start(I2C_MemMapPtr p) i2c_set_master_mode(p); i2c_set_tx_mode(p); / 结束信号 void i2c_stop(I2C_MemMapPtr p) i2c_set_sl

28、ave_mode(p); i2c_set_rx_mode(p); / 等待信号 void i2c_wait(I2C_MemMapPtr p) / wait flag while(p-S & I2C_S_IICIF_MASK)=0); / clear flag p-S |= I2C_S_IICIF_MASK; / 是否收到应答 bool i2c_get_ack(I2C_MemMapPtr p) if(p-S & I2C_S_RXAK_MASK) = 0) return true; else return false; void hal_i2c_init(void) / 使能I2C0的模块时钟 S

29、IM_SCGC4 |= SIM_SCGC4_I2C0_MASK; / 将PTD8引脚复用功能切换到I2C0_SCL PORTE_PCR24 = PORT_PCR_MUX(5); / 将PTD9引脚复用功能切换到I2C0_SDA PORTE_PCR25 = PORT_PCR_MUX(5); / 设置I2C的波特率 - 14 - I2C0_F = 0x20; / 使能I2C0模块 I2C0_C1 = 0x80; 2.3问题及解决方法 1. 问题: 配置I2Cx_F寄存器MULT位不为0时,Repeat start信号无法产生。I2C 的功能是通过I2C接口读取板载的加速度传感器MMA8451的数据

30、,并且I2C数据控制采用查询ACK标志位的方式,使用I2C驱动代码,在FRDM-KL25Z开发板上执行发现:程序总是停在i2c_wait(I2C0_B),进入这个函数内部,它实际上是停在while(p-S & I2C_S_IICIF_MASK)=0),一直等待传输完成的中断标志IICIF置位。 原因分析: 初步判断可能是上一步数据的传输 i2c_write_byte没有完成,导致IICIF未能被置位。于是通过示波器去捕捉这个过程,发现在执行 i2c_repeated_start(I2C0_B)时,KL25并没有产生一个 Repeat start信号。经过一番谷哥和度娘,终于在Kinetis L

31、的Errata中找到了答案:Repeat start cannot be generated if the I2Cx_FMULT field is set to a non-zero value. 这也就意味着,当 I2Cx_FMULT位被设置为非0值时,I2C Master不能产生一个Repeat start信号。而在应用程序的I2C初始化I2C_init代码中, 我恰好设置I2Cx_F MULT=01,这正好是符合了Errata描述的错误产生的条件。 解决方案: I2C的C1寄存器中MULT位是I2C SCL时钟的倍乘因子,用于控制I2C的波特率。为解决上面的问题,FSL官方提供了两种wo

32、rkaround的办法: 1)如果repeat start必须产生时,配置 I2Cx_FMULT为0; 2)在置位 I2Cx_F register (I2Cx_C1RSTA=1)的Repeat START产生位之前临时设置 I2Cx_F MULT,然后再在repeated start信号产生后恢复I2Cx_FMULT位的设置。 按照第一种方法,我修改程序中I2Cx_FMULT的设置从01到00,然后程序在FRDM-KL25Z 开发板上运行正常,能正常读取板载的加速度传感器MMA8451的数据。 2. 问题描述: I2C单字节读取时序问题。 KL25读取MMA8451的基本过程是: 1. 发送要

33、访问的从机地址及对从机的写命令 - 15 - 2. 发送要访问的从机的寄存器地址 3. 发送Repeat Start信号到从机 4. 发送要访问的从机地址及读命令 5. 读取从机返回的数据。 主机在从机读取DATA7:0之后返回NAK信号的,用于指示本数据是Master要接收的最后一个DATA,最后发送stop signal终止数据的传送。然后去读取从机返回的数据 i2c_read_byte(I2C0_B),发送NACK信号到从机i2c_give_nack(I2C0_B)。然而从KL25实际的物理时序的角度看,这个顺序是错误的,应该在读取从机返回的数据 i2c_read_byte(I2C0_B

34、)之前,首先发送NACK信号到从机i2c_give_nack(I2C0_B)。 原因: 主机发送的NACK信号只有在下一个数据接收之后才会被push到总线上,KL25的RM手册中的描述为the No acknowledge signal is sent to the bus after the following receiving data byte (if FACK is cleared)。 第三章 小结 在学期的最后我们展开了三周的嵌入式课程设计,课上,老师要求我们进行小组内的自主学习与实践,并在嵌入式开发板上实现三色灯的转换,键盘输入输出及重力加速度测试等功能。 - 16 - 经过一学

35、期的理论学习,我们已经能够掌握嵌入式的基本概念,但想要将知识转换为应用,还是遇到了不少困难的。安装CodeWarrior时遇到了版本问题,调试测试文件时遇到了头文件和库函数加载不了的问题,虽然都是些及其细微的方面,然只有动手去做的时候才能真正理解并掌握它。 在调试重力加速度模块的时候,我遇到了两个方面的问题,即在第二章中所提到repeat start信号无法产生和单字节读取时序问题,经过多方查询资料、请教同学,这些问题都得到了较好的解决。 在此实践中我明白了两个道理: 1. 注重理论的同时更加注重实践; 2. 学习中要勤学勤问,有时候一个人思考不出来的问题也许在别人的指 点下就能豁然开朗,少走很多弯路。 这些道理不仅适用在本次课程中,在别的学习实践中也同样适用。总之,这一次嵌入式实践课程给予了我非常大的帮助,我也从中学到了很多东西。 物联网工程 1241906103 杨梦茜 - 17 -

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号