基于stm32的led点阵光笔设计与实现毕业论文软件部分内容摘要:

钟 (RTC)和备份寄存器提供电源。 如图表 4 所示 12 图表 4 电源框图 低功耗 在系统或电源复位以后,微控制器处于运行状态。 运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。 当 CPU不需继续运行时,可以利用多个低功耗模式来节省功耗,例如等待某个外部事件时。 用户需要根据最低电源消耗,最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。 STM32F10xxx 有三中低功耗模式: 睡眠模式 (Cortex™M3 内核停止,外设仍在运行 ) 停止模式 (所有的时钟都以停止 ) 待机模式 ( 电源关闭 ) 此外,在运行模式下,可以通过以下方式中的一种降低功耗: 降低系统时钟 关闭 APB 和 AHB总线上未被使用的外设的时钟 通用和复用 I/O 每个 GPI/O 端口有两个 32 位配置 寄存器 (GPIOx_CRL, GPIOx_CRH),两个 32位数据寄存器 (GPIOx_IDR, GPIOx_ODR),一个 32 位置位 /复位寄存器 (GPIOx_BSRR),一个 13 16 位复位寄存器 (GPIOx_BRR)和一个 32 位锁定寄存器 (GPIOx_LCKR)。 每个 I/O 端口的特定硬件特征, GPIO 端口的每个位可以由软件分别配置成多种模式。 输入浮空 输入上拉 输入下拉 模拟输入 开漏输出 推挽式输出 推挽式复用功能 开漏复用功能 每个 I/O 端口位可以自由编程,然而 I/0端口寄存器必须按 32位字被访问 (不允许半 字或字节访问 )。 GPIOx_BSRR 和 GPIOx_BRR 寄存器允许对任何 GPIO 寄存器的读 /更改的独立访问;这样,在读和更改访问之间产生 IRQ 时不会发生危险。 图表 5 给出了 I/O 端口位的基本结构 图表 5 I/0端口位的基本结构 外部中断 /事件控制器( EXTI) 外部中断 /事件控制器由 19个产生事件 /中断要求的边沿检测器组成。 每个输入线可以独立地配置输入类型 (脉冲或挂起 )和对应的触发事件 (上升沿或下降沿或者双边沿都触发 )。 每个输入线都可以被独立的屏蔽。 挂起寄存器保持着状态线的中断要求。 EXTI 控制器的主要特性如下: 每个中断 /事件都有独立的触发和屏蔽 每个中断线都有专用的状态位 支持多达 19 个中断 /事件请求 检测脉冲宽度低于 APB2 时种宽度的外部信号 14 外部中断 /事件控制器框图如图表 6 所示: 图表 6外部中断 /事件控制器框图 如果要产生中断,必须事先配置好并使能中断线。 根据需要的边沿检测设置 2个触发寄存器,同时在中断屏蔽寄存器的相应位写 1允许中断请求。 当外部中断线上发生了需要的边沿时,将产生一个中断请求,对应的挂起位也随之被置 1。 在挂起寄存器的对应位写 1,可以清除该中断请求。 如果要为产生事件, 必须事先配置好并使能事件线。 根据需要的边沿检测通过设置 2 个触发寄存器,同时在事件屏蔽寄存器的相应位写 1 允许事件请求。 当事件线上发生了需要的边沿时,将产生一个事件请求脉冲,对应的挂起位不被置 1。 通过在软件中断 /事件寄存器写 1,也可以通过软件产生中断 /事件请求。 通过下面的过程来配置 19 个线路做为中断源: 配置 19 个中断线的屏蔽位 (EXTI_IMR)。 配置所选中断线的触发选择位 (EXTI_RTSR 和 EXTI_FTSR)。 配置那些控制映像到外部中断控制器 (EXTI)的 NVIC 中断通道的使能和屏蔽位,使得 19 个 中断线中的请求可以被正确地响应。 配置 19 个事件线的屏蔽位 (EXTI_EMR)。 配置事件线的触发选择位 (EXTI_RTSR 和 EXTI_FTSR)。 配置 19 个中断 /事件线屏蔽位 (EXTI_IMR, EXTI_EMR)。 设置软件中断寄存器的请求位 (EXTI_SWIER)。 通用 I/O 端口与 16 个外部中断 /事件的连接方式如图表 7 所示: 15 图表 7 外部中断通用 I/O映射 通用定时器 通用定时器是一个通过可编程预分频器驱动的 16 位自动装载计数器构成。 它适用于多种场合,包括测量输入 信号的脉冲长度 (输入捕获 )或者产生输出波形 (输出比较和 PWM)。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 定时器是完全独立的,而且没有互相共享任何资源,它们可以一起同步操作。 通用 TIMx (TIM TIM TIM4 和 TIM5)定时器功能包括: 16位向上、向下、向上 /向下自动装载计数器 16 位可编程 (可以实时修改 )预分频器,计数器时钟频率的分频系数为 1~ 65535之间的任意数值。 4 个独立通道:输入捕获、输出比较、 PWM生成 (边缘或中间对齐模式 )、单脉冲模 16 式输出。 使用外部信号控制定时器和定时器互连的同步电路 如下事件发生时产生中断 /DMA: ─更新:计数器向上溢出 /向下溢出,计数器初始化 (通过软件或者内部 /外部触发 ) ─触发事件 (计数器启动、停止、初始化或者由内部 /外部触发计数 )。 ─输入捕获 ─输出比较 ─支持针对定位的增量 (正交 )编码器和霍尔传感器电路 ─触发输入作为外部时钟或者按周期的电流管理 可编程通用定时器的主要部分是一个 16 位计数器和与其相关的自动装载寄存器。 这个计数器可以向上计数、向下计数或者向上向下双向计数。 此计数器时钟由预分频器 分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。 时基单元包含:计数器寄存器 (TIMx_CNT)、预分频器寄存器 (TIMx_PSC)、自动装载寄存器 (TIMx_ARR)。 图表 8 为内部时钟分频因子为 2 时的计数器时序图。 图表 8 计数器时序图 整体的系统流程图 本实验主要是通过四个按键来控制光笔在 32X32 点阵上的动作,包括点亮、笔画擦除,连字多写及休眠定时的设置。 具体的系统流程图如图表 9: 17 开 始 硬 件 初 始 化等 待 按 键 进 入 是 否 触 屏扫 描 L E D 屏是 否 有 光 信 号 返 回待机页面选择坐 标 点 亮整屏擦除笔画擦除反显测频数据存储初始化计数定时控制NYNNYY 图表 9 系统数据流图 32X32 点阵行列扫描的实现 主控制程序包括系统初始化( GPIO 的设置,时钟的设置,定时中断的设置等等),点阵扫描控制,按键功能的程序(点亮,反显,擦除,连字多写,休眠定时), 点阵扫描控制程序 分为行扫描与列扫描 , 行扫描由 STM32 的 GPI0C 口通过对四片 74LS273 的控制来实现循环点亮点阵的 32 行,同时通过对两片 74HC154 的控制来实现 32 列的循环点亮,为了尽可能的节省 GPIO 口,用到了片选,即 当需要点亮 某一芯片时 时, 控制对应的 GPIO 口输出 0其它芯片输出 1,只有该 芯 片有效,反之,控制片选无效, 从而达到节省 GPIO 的目的,利用微亮扫描过程实现 循环点亮 1024 个 点。 具体代码如下, /***********************************************/ //函数名 void Lsm() // 功能 列扫描函数,实现点阵 32 的逐一点亮灭, // 保证每一次只点亮一只 LED /***********************************************/ void Lsm(void) { unsigned char j。 Dl_Bit = 0x01。 Sm_Row = 0。 //列扫描次数初值 18 Gpioc_Ph = Gpioc_Phamp。 0xf0。 //GPIOC 缓存低四位清零 Gpioc_Ph = Gpioc_Phamp。 Dl_Bit。 //缓存列扫描信息 GPIO_Write(GPIOC,Gpioc_Ph)。 //微亮输出列 for(j = 0。 j 8。 j++) //扫描前 8列 { if(Bhzl) { Dl_Bit_Temp = S_Yle[Sm_Line+16][Clzl]amp。 Dl_Bit。 } else { Dl_Bit_Temp = S_Yle[Sm_Line][Clzl]amp。 Dl_Bit。 } if(0 ==Dl_Bit_Temp) { Gpioc_Ph = Gpioc_Ph|0xf00。 //不亮 } else { if(0 == Clzl) { //第一个 8位点亮 Gpioc_Ph = Gpioc_Ph|0xe00。 Gpioc_Ph = Gpioc_Phamp。 0xeff。 } else if(1 == Clzl) { //第二个 8位点亮 Gpioc_Ph = Gpioc_Ph|0xd00。 Gpioc_Ph = Gpioc_Phamp。 0xdff。 } else if(2 == Clzl) { //第三个 8位点亮 Gpioc_Ph = Gpioc_Ph|0xb00。 Gpioc_Ph = Gpioc_Phamp。 0xbff。 } else if(3 == Clzl) { //第四个 8位点亮 Gpioc_Ph = Gpioc_Ph|0x700。 Gpioc_Ph = Gpioc_Phamp。 0x7ff。 } } Gpioc_Ph = Gpioc_Phamp。 0xf00。 //GPIOC 缓存低八位清零 Gpioc_Ph = Gpioc_Phamp。 Dl_Bit。 //缓存列扫描信息 GPIO_Write(GPIOC,Gpioc_Ph)。 //微亮输出列 Delay_Ms(1)。 Sm_Row++。 19 Dl_Bit = 1。 //左移一位 if(0x100 == Dl_Bit)Dl_Bit = 0x01。 } }/***************************************************/ //函数名 void Lsm( voi) // 功能 点阵扫描函数,实现点阵 1024 个点的逐一点亮 // 从第一行开始按列扫描方式,从左往右逐一点亮 32 列上的 //32 个点 ,再换第二行再依次点亮,直到 1024 个点都亮灭一次 /******************************************************/ void Dzsm(void) { unsigned char k。 Gpioc_Ph = Gpioc_Ph|0xe00。 //微亮片选第一个 8位 Gpioc_Ph = Gpioc_Phamp。 0xeff。 //微亮片选第一个 8位 GPIO_Write(GPIOC,Gpioc_Ph)。 Bhzl = 0。 //行小于 16 Sm_Line = 0。 //行扫描次数 for(k = 0。 k 16。 k++) //行循环 16 次 0~15 { Blzl = 0。 //列小于 8 Clzl = 0。 Gpiod_Ph = Gpiod_Ph|0xd0。 //微亮片选低位 Gpiod_Ph = Gpiod_Phamp。 0xd0。 Gpiod_Ph = Gpiod_Ph|Sm_Line。 GPIO_Write(GPIOD,Gpiod_Ph)。 //微亮输出列 Lsm()。 //列扫描 Blzl = 1。 //列大于 8 小于 16 Clzl = 1。 Gpiod_Ph = Gpiod_Ph|0xd0。 //微亮片选低位 Gpiod_Ph = Gpiod_Phamp。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。