当前位置:首页 >> 信息与通信 >>

cortex-m3实用教程


第一部分 准备篇 第1章实验平台简介 1.1EK -LM3S811开发板简介 1.2主流入门 Cortex M3开发平台对比 第2章实验平台硬件资源详解 2.1开发板原理图详解 2.2开发板使用注意事项 第3章 RVMDK 软件入门 3.1RVMDK3.80A 简介 3.2新建 RVMDK 工程 3.3RVMDK 使用技巧 3.3.1文本美化 3.3.2代码编辑技巧 3.3.3其

他小技巧 3.3.4调试技巧 第4章下载与调试 4.1软件仿真 4.2程序下载 4.3S 硬件调试 第5章 SYSTEM 文件夹介绍 5.1delay 文件夹代码介绍 5.1.1delay_init 函数 5.1.2delay_μs 函数 5.1.3delay_ms 函数 5.2sys 文件夹代码介绍 5.2.1I/O 口的位操作实现 5.2.2Stm32_Clock_Init 函数 5.2.3Sys_Soft_Reset 函数 5.2.4Sys_SleepDeep 函数 5.2.5JTAG_Set 函数 5.2.6中断管理函数 5.3usart 文件夹介绍 5.3.1USART1_IRQHandler 函数 5.3.2uart_init 函数 第二部分 实践篇 第6章跑马灯实验 第7章按键输入实验 第8章串口通信实验 第9章外部中断实验 第11章窗口看门狗实验 第12章定时器中断实验 第13章 PWM 输出实验

第14章12864液晶显示实验 第15章 TFTLCD 显示实验 第16章 RTC 实时时钟实验 第17章待机唤醒实验 第18章 ADC 实验 第19章内部温度传感器实验 第20章 DMA 实验 第21章 I2C 实验 第22章 SPI 实验 第24章无线通信实验 第25章 SD 卡实验 第26章红外遥控实验 第27章 DS18B20实验 第28章 PS/2鼠标实验 第29章汉字显示实验 第30章图片显示实验 第31章触控 USB 鼠标实验 第32章制作 MP3播放器实验 第33章综合测试实验 参考文献

2009年 5月 18日,北京讯 日前,德州仪器 (TI)宣布收购市场领先的基于 ARM? Cortex?-M3的 32位 MCU 供应商 Luminary Micro,从而进一步壮大了其微处理器 (MCU)产品阵营。 成功收购 Luminary Micro 的 Stellaris?系列 Cortex-M3处理器将极大增强 TI 提供 业界最完整 MCU 产品系列的实力。此次收购意味着客户从现在开始即可体验 Stellaris MCU 丰富的创新功能,以及 TI 作为全球领先半导体供应商所拥有的卓 越用户体验与雄厚技术实力。 Stellaris 器件将有助于 TI 充分满足主流 32位 MCU 的市场需求,从而使客户能 够获得业界标准 ARM Cortex-M3内核的通用处理性能以及 Stellaris 产品系列的 高级通信功能,如 10/100以太网 MAC+PHY、CAN、USB OTG、USB 主机/装 置、 SSI/SPI、 UART、 I2S 以及 I2C 等。 此次收购的相关事项已于 2009年 5月 14 日处理完毕。 (更多详情,敬请访问:www.ti.com/stellarispr) TI 负责高级嵌入式控制业务的副总裁 Brian Crutcher 指出:“通过将 Luminary Micro 公司 Cortex-M3处理器卓越的设计体验与 TI 在超低功耗 MSP430 MCU 与 高性能 C2000?实时控制器方面拥有的广博专业技能完美结合, 可为 TI 客户提 供能够满足几乎所有应用领域的统一 MCU 来源——所有这些均可由业界最广泛 的嵌入式处理与模拟产品系列进行补充。” Stellaris 系列 MCU 定位于要求强大控制处理与连接功能的低成本应用,如运动

控制、远程监控、HVAC 与楼宇控制系统、网络设备与交换机、工厂自动化、电 子销售点机器、测量测试设备、医疗仪表以及娱乐设备等。最新推出的第四代 Stellaris 器件——LM3S9000 Series 在通用处理性能方面取得了全新突破, 并实现 了连接性、存储器配置以及高级运动控制的完美结合。 Luminary Micro 前首席执行官、现任总经理 Jim Reinhart 指出:“对于我们的客 户而言,今天发布的公告是一则重大新闻。今后,客户不仅可受益于屡获殊荣的 Stellaris 系列产品,还能充分享受 TI 强大的技术与制造实力,体验足迹遍布全 球、具有丰富经验的模拟与嵌入式处理技术领导者所带来的强大优势。” Jim Reinhart 将领导 TI Catalog ARM MCU 业务及其作为 TI 高级嵌入式控制 (AEC)机构不可分割一部分的发展策略的实施。Cortex-M3微处理器业务将继续 由位于德克萨斯州奥斯汀 (Austin, Texas)的基地运营,今后将会被命名为“TI AEC Austin”。 从通用超低功耗 MSP430 MCU 系列,到面向实时控制的高性能 TMS320C2000? MCU 系列,再加上目前基于 Cortex-M3的32位 MCU,TI 可提 供业界最广泛的嵌入式控制解决方案。设计人员可充分利用 TI 完整的软、硬件 工具,丰富的第三方产品以及全方位的技术支持,加速设计的上市进程

基于 ARM? Cortex?-M3的四款 MCU 套件

日前,德州仪器 (TI)宣布推出四款可支持基于 ARM Cortex-M3的第四代 Stellaris MCU 的低成本开发套件, 能够在工业、 消费类电子以及医疗应用等领域 对高级连接与复杂控制功能的需求不断增长的情况下, 充分满足对高性能集成微 处理器 (MCU)以及可靠配套工具与软件的需求。 最低价格为 99美元的全新套件 可帮助开发人员立即开展设计工作, 并充分发挥最新 32位 Stellaris MCU 的高级 连接性、数据高效性以及运动控制特性等优势。为进一步简化开发,每个套件均 包含有全面的 StellarisWare?外设驱动器库、图形库、USB 库以及代码示例。如 欲了解更多详情,敬请访问:www.ti.com/stellarispr。 两款全新评估套件、 一款开发套件与一款参考设计套件现已开始供货,可通过经 销商进行订购。每款套件都提供具有 256K 闪存、96K SRAM 以及 ROM 内置 StellarisWare 软件的 80 MHz Stellaris MCU,而且还提供集成以太网、USB 移动 (OTG)/主机/器件以及 CAN。 上述套件可满足开发人员进行设计的所有需求, 可在 10分钟乃至更短的时间内启动开发工作。 Stellaris?LM3S9B90 和 LM3S9B92以太网+USB-OTG 评估套件的特性与优势 ??

这两款评估套件提供可直接投入设计的两块电路板, 包括一个电路内部调试接口 电路板以及36毫米 x102毫米的 EK-LM3S9B90或 EK-LM3S9B92评估板; ?? 最新80 MHz LM3S9B90 MCU 为要求省电模式的应用提供了休眠模块, 可延长非 工作时间; ?? 针对要求同时存取外设与高级运动控制功能的应用, 80 MHz LM3S9B92 MCU 可 提供8个针对运动与能量的 PWM 输出以及两个正交编码器输入(QEI)模块,而且 还可提供最大化外设连接性能的选项; ?? 集成式高级连接外设包括以太网10/100、两个 LED 指示灯以及 USB 2.0全速 OTG; ?? 所有 MCU I/O 均采用可简化原型设计的标准尺寸终端排针(terminal header); ?? 第三方 ARM 工具厂商提供可简化开发的完整源代码、文档以及多种评估工具的 选择; ?? 如欲了解更多信息或购买套件,敬请访问:www.ti.com/lm3s9B90evalkits-pr 或 www.ti.com/lm3s9B92evalkits-pr。 DK-LM3S9B96开发套件的特性与优势 ?? 特性丰富的开发平台提供可简化菜单导航的3.5英寸景观型 QVGA TFT 彩色 LCD 显示屏与指轮电位计; ?? ROM 内置的 SafeRTOS 可用作标准操作系统,也可用作要求通过 IEC61508或 FDA510(k)认证的高度完整性应用的一部分; ?? 高度集成的80 MHz Stellaris LM3S9B96 MCU; ?? 两个外设接口(EPI)子板,一个采用8MB SDR SDRAM 存储器,另一个可便捷访 问所有32 EPI 引脚; ?? 具有外部音频编解码器与接口的集成型跨芯片音响(I2S)接口支持线路输入输出、 麦克风输入与耳机输出; ?? MicroSD 卡插槽、1 MB 串行闪存、高精度3V 模拟参照电压; ?? 第三方 ARM 工具厂商提供可简化开发工作的 StellarisWare 软件与评估工具; ?? 如欲了解更多详情或购买套件,敬请访问:www.ti.com/dk-lm3s9b96-pr。

3.5英寸景观型单板计算机智能显示参考设计套件(RDK-IDM-SBC) 的特性与优 势 ?? 经过成本与外形优化设计的人机接口(HMI)触摸显示面板实例适用于嵌入式控 制设备; ?? 高度集成的80 MHz Stellaris LM3S9B92 MCU 和扩展的板级存储器(包括8MB SDRAM、1MB 串行闪存、连接外部大容量存储设备的 USB 主机连接器,以及 一个用于影像、数据与代码存储的 MicroSD 卡插槽) ; ?? 3.5英寸景观导向型 QVGA 16位彩色 LCD 电阻式触摸面板显示屏(带白色 LED 背光) ; ?? 串行、数字模拟连接选项包括10/100以太网 RJ45插孔、USB 2.0 Type A 连接器、 通过终端功能块接口实现的 CAN 以及通过扩展排针实现的 UART 与 I2C; ?? 具有功率放大器的 I2S 音频编解码器可驱动一个8欧姆外部扬声器; ?? 如欲了解更多详情或购买套件,敬请访问:www.ti.com/rdk-idm-sbc-pr。 TI 丰富的 MCU 与软件产品系列 TI 可提供业界最丰富的嵌入式控制解决方案, 从通用超低功耗 MSP430 MCU 到 高性能实时控制 TMS320C2000? MCU,乃至最近推出的基于 Cortex-M3的 32 位 MCU,一应俱全。设计人员可充分利用 TI 完整的软硬件工具、丰富的第三 方产品以及全方位的技术支持,加速设计方案的上市进程。

1,LM3s811有什么优势? LM3S3xx,6xx,8xx 是 Stellaris 里面配置最平民化的产品。这个系列不带 USB, CAN, Enet 接口。 而 LM3S811这颗芯片在这个系列中是比较有代表性的一款。 所以: 1. LM3S811因不带高级外设,是作为入门级的比较好的一个选择。 2. 使用 LM3S811开发入门或者完成设计以后,可以 pin topin 向下兼容 LM3S6xx,3xx 的软件代码。 3. 还有,性价比高。 4. 显然是我们的主推产品,我们称之为 Hero Product。 5. 主推产品,性价比高,当然出货量大咯。 2,EK_LM3S811为何要设置那么多过孔? 在走线时候上下两层的地应该打上均匀分布,数量适当的过孔,以减少上

下层的电容效用。 3,EK_LM3S811移植 μ COSII 有什么好处? 到 ucos 的官网上有现成的 TI M3版本,不用移植。 (它提供的 IAR 版本的, MDK 的没有。 ) 4,EK_LM3S811上的白条是液晶么? 不是,是导光板。 5,请教 EK-LM3S811用作调试器调试外部芯片要怎么弄? 可以通过 jtag 口对外进行仿真。不要外接 jtag 来仿真开发板,开发板的 jtag 口是对外仿真的,如果接在一 起,连个 jtag 仿真电路会有冲突。 6,LM3S811串口下载程序问题? LM3S811开发板中自带 boot_serial 中,自动检测某个 GPIO 引脚(该引脚的 作用是接收更新程序的信号) 是被屏蔽掉的。出厂的芯片中的 boot_serial 只检 测2K(默认的应用程序起始位置)处是否存在有效的堆栈指针和复位向量,如果 有的话则执行应用程序, 如果没有则调用接收更新程序的代码(当然刚出厂的芯 片 2K 后是不会有应用程序的,所以刚出厂的芯片第一次连串口用 LM Flash Programmer 下载程序是没有问题的) , 但是第一次用串口下载程序后 (从2K 处写) 就不满足再调用接收更新程序的代码的条件了(2K 处已经有了有效 的堆栈指针 和复位向量) ,所以就不能下载程序了。我想问的是为什么芯片在出厂时不把检 测某个 GPIO 口作为更新程序的信号打开呢?如果想多次下载程序, 芯 片第一次 必须下载自己定义的 boot_serial, 这样的话, 每个芯片就必须下载两次程序 (一 个改写后的 boot_serial,一个自己的应用程序, 感觉写两次很麻烦) ,有没有 好的解决办法呢? 解答: 1. 我想问的是为什么芯片在出厂时不把检测某个 GPIO 口作为更新程序的 信号打开呢?出厂时并不知道客户用哪个 GPIO 方便,这个是可以自定义的。 2. 如果想多次下载程序,芯片第一次必须下载自己定义的 boot_serial, 这样的话,每个芯片就必须下载两次程序(一个改写后的 boot_serial,一个自 己的应用程序,感觉写两次很麻烦) ,有没有好的解决办法呢?谢谢了。 811没有内置 ROM Software,出厂烧在 flash 的 bootloader,应该是引导 到从 0 开始的 flash 地址的,并不是 2k 地址开始,也就是说,你使用出厂的 bootloader 烧写完程序后,出厂的 bootloader 就被覆盖了。dustdevil 系列以 后的产品,内置 ROM 中有 bootloader,可以通过程序设定检测某个 GPIO 来触发 下载程序。 7,通过 LM3S811采集的数据能不能通过 keil 软件调试?ADC 的采样序列到底是 什么意思啊? 可以看相应的寄存器,来查看采样到的数值。采样序列,会按照预先配置的 顺序来自动进行采样,减轻 CPU 负荷,且能配置优先级。 8,LM3S811可以用 ARM 指令编程吗?

M3只支持 thumb-2指令集。 9,LM3S811的 PWM 输出问题? 用 MDK 写了一个 LM3S811的 PWM 输出程序,有个疑问:

//Set PWM Pulse Wideth PWMPulseWidthSet(PWM_BASE, PWMPulseWidthSet(PWM_BASE, PWMPulseWidthSet(PWM_BASE, PWMPulseWidthSet(PWM_BASE, PWMPulseWidthSet(PWM_BASE, PWMPulseWidthSet(PWM_BASE,

PWM_OUT_0, PWM_OUT_1, PWM_OUT_2, PWM_OUT_3, PWM_OUT_4, PWM_OUT_5,

0); //设置 PWM 的脉冲宽度 1); 12000); 23998); 23999); 24000);

PWM 频率设置成了250Hz,对应于24000个时钟周期,当脉宽宽度设置成0、 23999、24000,PWM 出来都是高电平,如下图所示:MDK 自带的 Logic Analyzer

PWMTest.jpg (177.91 KB)

2011-6-24 12:08 那 PWMPulseWidthSet(unsigned longulBase, unsigned long

ulPWMOut,unsigned long ulWidth)的脉宽值设置成什么的时候,才会有全低的 电平出来呢? 继续弄了一下,发现可以通过 PWMOutputState(PWM_BASE,PWM_OUT_0_BIT, false)出来低电平,不知还有没有其它方法: // Enables the PWM generator block. PWMGenEnable(PWM_BASE, PWM_GEN_0); //使能 PWM 发生器,开始产生 PWM 波 PWMGenEnable(PWM_BASE, PWM_GEN_1); PWMGenEnable(PWM_BASE, PWM_GEN_2); SysCtlDelay(0xffff); PWMOutputState(PWM_BASE, PWM_OUT_0_BIT, false); PWMOutputState(PWM_BASE, PWM_OUT_1_BIT, false); PWMOutputState(PWM_BASE, PWM_OUT_2_BIT, false); PWMOutputState(PWM_BASE, PWM_OUT_3_BIT, false); PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, false); PWMOutputState(PWM_BASE, PWM_OUT_5_BIT, false); SysCtlDelay(0xffff); PWMOutputState(PWM_BASE, PWM_OUT_0_BIT, true); //使能 PWM 输出 PWMOutputState(PWM_BASE, PWM_OUT_1_BIT, true); PWMOutputState(PWM_BASE, PWM_OUT_2_BIT, true); PWMOutputState(PWM_BASE, PWM_OUT_3_BIT, true); PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, true); PWMOutputState(PWM_BASE, PWM_OUT_5_BIT, true); while(1) { ; }

10,LM3S811 设置 pll 问题 SysCtlClockSet(SYSCTL_SYSDIV_10| SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ); 设置以后为什么系统时钟总是显示 32.4MHz ? 设置 PLL 之前必须先将 LD0 设置为 2.75V 设置结束以后再设置为 2.50V, 如果你 不设置 LDO 应该是 PLL 不生效的。 11,lm3s811 不用 U-cos 如何实现多任务
一个在 cortex-M3 上运行的操作系统,已经过数十个产品验证。

代码很短,如果不算注释只有200行左右,及其短小,但很好用 http://bbs.eeworld.com.cn/viewthread.php?tid=97654 12,LM3S811 FIFO 接收 我把接收 FIFO 设为了4字节触发,PC 一下发了6个字节数,想请问下剩下的两 个在什么时候会收到呢,还有就是我在中断接收中处理收到的4个字节时剩下的 两个会不会丢失呢??? uart 的 FIFO 是16个字节,设置4字节触发,只是 FIFO 中超过4字节触发中 断,不影响后面字节的接收;如果 FIFO 中收到16个字节,还不把数据取走,才 会丢失数据。 13,LM3S811中防 JTAG 失效的函数中有个 KEY,这个 key 有何用 按住按键,程序就不向下运行了,也就不会执行锁住 jtag 的程序。
验3 基于 EK-LM3S811实现内部温度检测

模数转换器(ADC)外设用于将连续的模拟电压转换成离散的数字量。

该 Stellaris ADC 模块的转换分辨率为10位,并支持4个输入通道,以及一个内部温度 传感器。ADC 模块含有一个可编程的序列发生器,它可在无需控制器干涉的情况下对多个模 拟输入源进行采样。

内部温度传感器:

内部温度传感器提供了模拟温度读取操作和参考电压。 输出终端 SENSO 的电压通过以下 等式计算得到:

SENSO= 2.7 - ((T +55) / 75)

关于中断设置: 打开启动文件 Startup.s 文件,找到想要设置的中断然后命名,假如你想用 SysTick 中断,那么在 Startup.s 文件中找到

这一行, 将 IntDefaultHandler 更换为你想要命名的中断函数名 SysTick_ISR, 再另起 一行声明你用的中断函数 extern SysTick_ISR,这样配置的中断就可以使用了。

设置 ADC3的函数入口:

重新命名并且声明,

测试截图:

源程序: #include<lm3sxxx.h> #include<stdio.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long ulong Sysclk =12000000UL; tBoolean flag = false; void jtagWait(void); // 防止 JTAG 失效 void clockInit(void); // 系统时钟初始化 void uartinit(void); void put(const char *x); void wellcome(void ); void SysTickInit(void); void adcinit(void); void tmpDisplay(ulong ulValue); ulong adcSample(void); int main(void) {

ulongulValue; jtagWait(); clockInit(); uartinit(); adcinit(); SysTickInit(); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC| SYSCTL_PERIPH_GPIOE | SYSCTL_PERIPH_GPIOD); // 使能 KEY 所在的 GPIO 端口 SYSCTL_PERIPH_GPIOB |

GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0| GPIO_PIN_1); // 设置 KEY 所在管脚为输入 GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE,GPIO_PIN_0| GPIO_PIN_1); // 设置 KEY 所在管脚为输入 GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_0| GPIO_PIN_1); // 设置 KEY 所在管脚为输入 GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,GPIO_PIN_5); // 设置 KEY 所在管脚为输入 GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0| GPIO_PIN_1,0x00); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0 |GPIO_PIN_1,0x00); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0| GPIO_PIN_1,0x00); wellcome();

while(1)

{ SysCtlSleep( ); // 睡眠,减少耗电以降低温度

ulValue = adcSample( );// 唤醒后 ADC 温度采样

tmpDisplay(ulValue); } }

// 通过 UART 显示芯片温度值

// 防止 JTAG 失效 void jtagWait(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4);

//使能 KEY 所在的 GPIO 端口 //设置 KEY 所在管脚为输入

if(GPIOPinRead(GPIO_PORTC_BASE,GPIO_PIN_4) == 0x00);//若复位时按下 KEY,则进入 { while(1); //死循环,以等待 JTAG 连接 } SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOC);//禁止 KEY 所在的 GPIO 端口 } void clockInit(void) { SysCtlLDOSet(SYSCTL_LDO_2_75V); SysCtlClockSet(SYSCTL_XTAL_6MHZ |SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |SYSCTL_OSC_MAIN ); // The crystal is 50MHz Sysclk=SysCtlClockGet(); } void uartinit(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0 |GPIO_PIN_1); UARTConfigSet(UART0_BASE,115200,UART_CONFIG_WLEN_8| UART_CONFIG_PAR_NONE); UARTEnable(UART0_BASE); } void put(const char *x) { while(*x!='\0') UART_CONFIG_STOP_ONE |

{

UARTCharPut(UART0_BASE,*(x++)); } } void wellcome() { put("hello,21ic!\r\n"); SysCtlDelay(Sysclk); } void adcinit(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);//时钟使能 SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS);// 设置 ADC 采样速率 ADCSequenceDisable(ADC_BASE, 3);// 配置前先禁止采样序列 ADCSequenceConfigure(ADC_BASE,3,ADC_TRIGGER_PROCESSOR,0); //ADC0 触发一直有效,优先级 0

ADCSequenceStepConfigure(ADC_BASE,3,0,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END); //ADC0 步进 0,完成采样后,使能中断,通道 0(ADC0) ADCIntEnable(ADC_BASE,3); //三个中断使能 IntEnable(INT_ADC3); IntMasterEnable(); //采样使能 ADCSequenceEnable(ADC_BASE,3); } void SysTickInit(void) { SysTickPeriodSet(Sysclk);// 设置 SysTick 计数器的周期值 SysTickIntEnable(); // 使能 SysTick 中断 IntMasterEnable(); // 使能处理器中断 SysTickEnable(); // 使能 SysTick 计数器 } void tmpDisplay(ulong ulValue) { ulongulTmp; charcBuf[40]; ulTmp =151040UL - 225 * ulValue; sprintf(cBuf,"%ld.", ulTmp / 1024); put(cBuf); sprintf(cBuf,"%ld", (ulTmp % 1024) / 102);

put(cBuf); put("℃\r\n"); } // ADC 采样 ulong adcSample(void) { ulongulValue; ADCProcessorTrigger(ADC_BASE,3); // 处理器触发采样序列 while(!flag);// 等待采样结束 flag =false;// 清除 ADC 采样结束标志 ADCSequenceDataGet(ADC_BASE,3, &ulValue); // 读取 ADC 转换结果 return(ulValue); } void ADC3_ISR(void) { ulongvalue; value=ADCIntStatus(ADC_BASE,3,true); ADCIntClear(ADC_BASE,3); if(value!=0) { flag=true; } } // SysTick 计数器的中断服务函数 void SysTick_ISR(void) {

// 仅用于唤醒 CPU,而不需要做其他事情 }

PWM

实验4 基于脉宽调制器实现2路 PWM 输出控制 LED 亮度

本文中程序可以控制 LED5(蓝色)和 LED6(红色)由亮到暗的连续变 化。

每个 Stellaris PWM 模块提供3个 PWM 发生器模块和1个输出控制模块。每个 发生器模块有2个 PWM 输出信号,它们可以单独操作,或者作为带有插入死区延 时的一对信号来使用。 每个发生器模块还有一个中断输出和一个触发输出。控制 模块决定了 PWM 信号的极性以及哪些信号经过模块到达管脚。 Stellaris PWM 模块具有的特性有:

3个发生器模块,每个包含:

>>1个16位的递减或递增/递减计数器 >> 2个比较器 >> PWM 发生器 >> 死区发生器

控制模块

>>PWM 输出使能 >> 输出极性控制

>> 同步 >> 故障处理 >>中断状态

Stellaris 系列 ARM 提供的 PWM 模块功能非常强大,可以应用于众多方面: >> PWM 作为16为高分辨率 D/A 16位 PWM 信号 + 低通滤波器 + 输出缓冲器,如图所示:

>> PWM 调节 LED 亮度 不需要低通滤波器,通过功率管还可以控制电灯泡的亮度。 >> PWM 调节 LED 亮度 不需要低通滤波器,通过功率管还可以控制电灯泡的亮度。 >> PWM 演奏乐曲、语音播放 PWM 方波可直接用于乐曲演奏。作为 D/A 经功放电路可播放语音。 >> PWM 控制电机 直流电机 交流电机 步进电机 Stellaris 系列 ARM 支持多种系统时钟来源,如外接晶振、内部振荡器、

内部 PLL 等。源程序中 clockInit( )函数给出了采用外部 6MHz 晶振和采用内部 PLL 的典型配置方法。 默认的配置是外接 6MHz 晶振, PLL 配置部分被“/*...*/” 注释掉了,如果要启用 PLL 可去掉注释。 在 clockInit( )函数里,库函数 SysCtlLDOSet( )的作用是设置 LDO 的输 出电压。LDO 是“Low Drop-Out”的缩写,是片内集成的低压差线性稳压器,这 就为用户节省了一个外部的电源稳压器。LDO 输出电压在 2.25~2.75V 之间,步 进 50mV,可通过调用库函数 SysCtlLDOSet( )来设置。LDO 输出直接连到 LDO 第 6 管脚,也可为处理器内核提供稳定可靠的电源。 芯片内部有个 PLL(锁相环)单元,能够把输入的较低频率时钟信号锁定 到 200MHz 输出。当然处理器内核最高只能工作在 50MHz,因此必须要进行 4 以 上的分频。但是,要当心:在启用 PLL 之前必须要把 LDO 输出电压设置在最高的 2.75V。 这是因为 PLL 单元会消耗较大的功率, 再加上芯片其它的功耗, 如果 LDO 电压不够高就容易造成死机。

一、使用 Keil uVision4的建立 lcdtest 工程项目
(1)首先新建一个文件夹

(2)把要建立的工程项目文件夹进行命名为 lcdTest

(3)在文件夹里新建6个 TXT 文件。

(4) 分别对6个 TXT 文本命名为 mian.c、 st7920.c、 st7920.h、 delay.c、 delay.h、Type.h

(5)找到 TI 给的驱动库文件 driverlib 与 inc 文件夹,然后复制到 lcdTest 目录下

(6)打开安装好的 keil uvision

(7)打开后找到 project 栏目,找到 new uvision project,点击新建一个 工程项目

(8)在刚刚新建的文件夹里新建这个工程项目,工程项目命名为 lcdTest。

(9)项目找到你对于的 CPU,这里选择流明系列为 Luminary Micro

(10)选择芯片 LM3S811

(11)提示是否需要写入中断列表,点是

(12)项目树列表如下:

(13) 在项目数字添加新的组, Target 1右键, 选择下列列表中的 Add group.

(14)把新建的组命名为:drive.驱动

(15)在改组中添加文件。点击 add files to group""

(16) 找到 TI 给的驱动库文件 (也就是刚拷贝在 lcdTest 目录下的 driverlib 文件夹) , 点击其中的 driverlib 文件包,其中里面 rvmdk 就是 KEIL 的驱动.lib

(17) 打开 rvmdk 文件包, 找到 driverlib,lib 点击 ADD 或者双击文件添加。

(18)添加后的工程树目录

(19)然后添加程序

(20)然后添加刚才建立的添加 mian.c、delay.c、st7920.c

(21)项目建立成功

(22)点击点击 Target Options

(23)仿真器选择分别在 Debug 和 utilities 中设置

(24)双击 mian.c 函数

(25)在 mian.c 函数添加头文件并加入 int mian(void)函数并编译成功

(26)对于 st7920.c、st7920.h、delay.c、delay.h、Type.h 的代码 编写请参照工程文件。 (27)编辑代码并编译通过后即可点击 Download 按钮进行下载程序了。

二、

工程文件代码展示

(1) main.c #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "st7920.h" #include "Type.h" #include "delay.h" INT32U TheSysClock; //定义全局的系统时钟变量

/****************************************************************************** ******** 函数名: int main(void) 功 能: 测试 LCD12864 单色液晶 说 明: 显示一张图片,分辨率为 128*64 输 入:无 输 出:无 其 他:初始化可分为以下步骤: 1:防止 JTAG 死锁 2:配置系统时钟,保证板子能正常工作起来 3:使能 GPIO 端口外设,也就是开 GPIO 功能。 4:设置 LCD 管脚为输出管脚。 5:初始化 LCD,保证 LCD 正常工作 ******************************************************************************* *******/ int main(void) { /**********JTAG 防止死锁*************/ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); GIOPC GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_4); // 设置 USER 按键所在管脚为输入 if (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_4) == 0x00) //若复位时按下 USER 按 键,则进入 { for (;;); // 死循环, 以等待 JTAG 连接 } SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOC); //禁止 USER 按键所在的 GPIO 端口

// 使 能 外 设

/***********配置系统时钟 *********/ SysCtlClockSet(SYSCTL_SYSDIV_1 //不分频 SYSCTL_USE_OSC //系统时钟设置 SYSCTL_OSC_MAIN //采用主振荡器 SYSCTL_XTAL_6MHZ); //外接 6MHz 晶振 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_2 |GPIO_PIN_3|GPIO_PIN_5); TheSysClock = SysCtlClockGet(); 频率 open_lcd(); //初始化 12864 液晶 start_logo(); 为 128*64 /* 向液晶缓冲区写入数据 */ write_char_buf(0, 0, "TI LM3S811 开发板"); write_char_buf(1, 0, "TI Stellaris M3 "); write_char_buf(2, 0, " 感谢 21IC "); write_char_buf(3, 0, " 感谢 TI "); //进入循环处理用户代码 while(1) { delay10ms(10); lcd(); } } (2) st7920.c 文件 #include <string.h> #include "st7920.h" #include "Type.h" #include "delay.h"

| | |

//获取当前的系统时钟

// 显示显示图片, 分辨率

INT16U buf_lcd_char[4][8];

// LCD 文字显示缓冲区

/******************************************************************************

******** 名称:void start_logo(void) 说明: 开机画面显示 输入:image_logo[] 开机画面信息 输出:无 ******************************************************************************* *******/ INT8U const logo_image[1024] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0xEC,0xF0,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0xCD,0xF0,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x8C,0xF0,0x06,0x3F,0x73,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x08,0x70,0x06,0x31,0x32,0x1C,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x1F,0x18,0x78,0x06,0x30,0x3E,0x1C,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x07,0xFF,0x18,0xF8,0x06,0x3E,0x1C,0x26,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03,0xFF,0x9B,0xFC,0x06,0x32,0x1C,0x26,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0xFF,0x9B,0xFC,0x06,0x30,0x16,0x7E,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x93,0xFC,0x06,0x30,0x26,0x43,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x93,0xFC,0x07,0x3F,0x63,0xC3,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x7F,0x81,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x61,0x81,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x81,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFE,0x00,0x06,0x61,0x3E,0xFE,0xF8,0xC2,0x60,0xCF,0x98,0x5F,0xCF,0x00, 0x00,0x00,0x7C,0x00,0x06,0x71,0x22,0xB2,0xCC,0xC2,0x71,0xCC,0x1C,0x57,0x59,0x00, 0x00,0x00,0x7C,0x00,0x06,0x79,0x60,0x10,0xC6,0xC2,0x71,0xC8,0x1E,0x42,0x10,0x00, 0x00,0x00,0x3C,0x00,0x06,0x6D,0x3C,0x30,0xCC,0xC2,0x52,0xCF,0x97,0x42,0x1E,0x00, 0x00,0x00,0x1E,0x00,0x06,0x67,0x1E,0x30,0xF8,0xC2,0x5A,0xCF,0x93,0xC2,0x0F,0x80, 0x00,0x00,0x00,0x00,0x06,0x67,0x03,0x10,0xCC,0xC2,0x4C,0xC8,0x11,0xC2,0x01,0x80, 0x00,0x00,0x00,0x00,0x06,0x63,0x43,0x30,0xCC,0xC6,0x4C,0xCC,0x10,0xC2,0x11,0x80, 0x00,0x00,0x00,0x00,0x07,0x61,0x3E,0x30,0xC6,0x7C,0x48,0xCF,0xD8,0x47,0x1F,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; void start_logo(void) { //INT8U *ptr_logo; INT8U i, j; INT16U addr; INT8U tmp_data[32]; /* 显示信息 */ //ptr_logo = (INT8U *)logo_image; for (i = 0; i < 32; i++) { /* 组织数据 */

addr = i * 16; for (j = 0; j < 16; j++) { tmp_data[j] = logo_image[addr + j]; tmp_data[j+16] = logo_image[512+addr+j]; } addr = i; addr <<= 8; write_st7920(ST7920_RAM_GDRAM, addr, tmp_data, 32); // __RESET_WATCHDOG(); } /* 开机画面,等待 3s */ delay10ms(300); } /****************************************************************************** ******** 名称:void open_st7920(void) 说明: 液晶初始化函数 输入:无 输出:无 ******************************************************************************* *******/ void open_st7920(void) { /* Set function RE = 0 */ send_cmd_st7920(0x30); /* Set Entry point */ send_cmd_st7920(0x06); /* Turn on display */ send_cmd_st7920(0x0C); /* Clear screen */ send_cmd_st7920(0x01); /* Set function RE = 1 */ send_cmd_st7920(0x34); /* Set SR = 0 */

send_cmd_st7920(0x20); } /****************************************************************************** ******** 名称:void send_cmd_st7920(INT8U cmd) 说明: 发送一个命令至 st7920 输入:无 输出:无 ******************************************************************************* *******/ void send_cmd_st7920(INT8U cmd) { INT8U sbyte = 0xF8; INT8U i = 0; ST7920_CLK_0(); ST7920_CS_1(); /* 输入前导字节 */ for (i = 0; i < 8; i++) { ST7920_CLK_0(); if (sbyte & 0x80) { ST7920_DI_1(); } else { ST7920_DI_0(); } ST7920_CLK_1(); sbyte <<= 1; } /* 输入命令码高 4 位 */ sbyte = cmd & 0xF0; for (i = 0; i < 8; i++) { ST7920_CLK_0(); if (sbyte & 0x80) {

ST7920_DI_1(); } else { ST7920_DI_0(); } ST7920_CLK_1(); sbyte <<= 1; }

/* 输入命令码低 4 位 */ sbyte = cmd << 4; for (i = 0; i < 8; i++) { ST7920_CLK_0(); if(sbyte & 0x80) { ST7920_DI_1(); } else { ST7920_DI_0(); } ST7920_CLK_1(); sbyte <<= 1; } ST7920_CS_0(); /* 等待命令执行 */ delay1ms(1); if (cmd == 0x01) { delay10ms(1); } } /****************************************************************************** ******** 名称:void send_data_st7920(INT8U ptr_data, INT8U len) 说明: 写数据至液晶

输入:ptr_data:数据起始地址 len:数据长度 输出:无 ******************************************************************************* *******/ void send_data_st7920(INT8U *ptr_data, INT8U len) { INT8U sbyte = 0xFA; INT8U i = 0; INT8U j = 0; ST7920_CS_1(); /* 输入前导字节 */ for (i = 0; i < 8; i++) { ST7920_CLK_0(); if (sbyte & 0x80) { ST7920_DI_1(); } else { ST7920_DI_0(); } sbyte <<= 1; ST7920_CLK_1(); } /* 输入数据 */ for (j = 0; j < len; j++) { /* 输入数据字节高 4 位 */ sbyte = ptr_data[j] & 0xF0; for (i = 0; i < 8; i++) { ST7920_CLK_0(); if (sbyte & 0x80) { ST7920_DI_1(); }

else { ST7920_DI_0(); } sbyte <<= 1; ST7920_CLK_1(); } /* 输入数据字节低 4 位 */ sbyte = ptr_data[j] << 4; for (i = 0; i < 8; i++) { ST7920_CLK_0(); if (sbyte & 0x80) { ST7920_DI_1(); } else { ST7920_DI_0(); } sbyte <<= 1; ST7920_CLK_1(); } } /* 延时等待数据写入完成 */ delay1ms(1); ST7920_CS_0(); } /****************************************************************************** ******** 名称:void write_st7920(INT8U ram, INT16U addr, INT8U *p_data ,INT8U len) 说明:向指定的 RAM 写入数据 输入: ram: RAM 区号 0-DDRAM 1-IRAM 2-CGRAM 4-GDRAM addr: 写入起始地址 p_data: 数据起始地址 len: 数据长度 输出:无

******************************************************************************* *******/ void write_st7920(INT8U ram, INT16U addr, INT8U *p_data, INT8U len) { INT8U addr_ram = 0x00; /* 要操作的 RAM 起始地址 */ /* 目标 RAM 选择 */ switch (ram) { case ST7920_RAM_DDRAM: send_cmd_st7920(0x34); send_cmd_st7920(0x30); addr_ram = (INT8U)addr; addr_ram &= 0x3F; addr_ram |= 0x80; send_cmd_st7920(addr_ram); break; case ST7920_RAM_IRAM: send_cmd_st7920(0x34); addr_ram = (INT8U)addr; addr_ram &= 0x0F; addr_ram |= 0x40; send_cmd_st7920(addr_ram); break; case ST7920_RAM_CGRAM: send_cmd_st7920(0x30); addr_ram = (INT8U)addr; addr_ram &= 0x3F; addr_ram |= 0x40; send_cmd_st7920(addr_ram); break;

/* Function Set GD Disable */ /* Function Set RE=0 */

/* Set DDRAM address */

/* Function Set RE=1 */

/* Set SEGRAM address */

/* Function Set RE=0 */

/* Set CGRAM address */

case ST7920_RAM_GDRAM: send_cmd_st7920(0x36); /* Function Set GD Enable */ addr_ram = (INT8U)(addr >> 8); addr_ram &= 0x7F; addr_ram |= 0x80; send_cmd_st7920(addr_ram); /* 发送行(垂直)地址 */ addr_ram = (INT8U)addr; addr_ram &= 0x0F; addr_ram |= 0x80;

send_cmd_st7920(addr_ram); break; default: return; } /* 写入数据 */ send_data_st7920(p_data, len); }

/* 发送列(水平)地址 */

/****************************************************************************** ******** 名称:void init_lcd(void) 说明: 初始化 LCD 显示 输入:无 输出:无 ******************************************************************************* *******/ void open_lcd(void) { INT8U i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 8; j++) { buf_lcd_char[j] = 0xA1A0;
} } open_st7920(); }

/*********************************************************************** ***************

名称:void write_char_buf(INT8U row, INT8U col, INT8U *pc) 说明: 装载文字缓冲区 输入:无 输出:无
************************************************************************ **************/

void write_char_buf(INT8U row, INT8U col, INT8U *pc) { INT8U r = row & 0x03u; INT8U c = col & 0x07u; INT8U i; INT8U k; INT8U len; if (pc == NULL) return; len = strlen(pc); for (i=0,k=c; 2*i<len;i++) { /* #if 0 buf_lcd_char[r][k] = (pc[2*i]<<8); buf_lcd_char[r][k++] += pc[2*i+1]; if(len%2==1&&i==(len/2-1)) { buf_lcd_char[r][k] } #endif */ = pc[2*i]; buf_lcd_char[r][k] = (pc[2*i+2]<<8);

buf_lcd_char[r][k++] += (pc[2*i+1]<<8); if(len%2==1&&i==(len/2-1)) { buf_lcd_char[r][k] } } } = pc[2*i+2];

/*********************************************************************** ***************

名称:void lcd(void) 说明: LCD 显示模块接口程序 输入:buf_lcd_char[] 输出:无
************************************************************************ **************/ void lcd(void) { INT8U static ddram_row = 0; /* 刷新行号,每次刷新一行 */ LCD 文字显示缓冲区

INT8U *ptr_data; INT8U lcd_row = 0; INT8U lcd_col = 0; /* ASCII 字符码转 GB 字符码 */ for (lcd_row = 0; lcd_row < 4; lcd_row++) { for (lcd_col = 0; lcd_col < 8; lcd_col++) { if ( { buf_lcd_char[lcd_row][lcd_col] += 0xA380; } } } /* 选择行 */ switch (ddram_row) { case 0: break; case 1: break; case 2: break; case 3: break; default: break; } ptr_data = (INT8U *)buf_lcd_char[lcd_row]; write_st7920(ST7920_RAM_DDRAM, ddram_row * 8, ptr_data, 16); ddram_row++; if (ddram_row >= 4) { ddram_row = 0; /* LCD 缓冲区 3 行对应 DDRAM 3 行 */ /* LCD 缓冲区 2 行对应 DDRAM 1 行 */ /* LCD 缓冲区 1 行对应 DDRAM 2 行 */ /* LCD 缓冲区 0 行对应 DDRAM 0 行 */ lcd_row = 0; buf_lcd_char[lcd_row][lcd_col] <= 125 && buf_lcd_char[lcd_row][lcd_col] >= 32 )

lcd_row = 2;

lcd_row = 1;

lcd_row = 3;

} }

三、(3)

st7920.h 文件

#ifndef _12864_H #define _12864_H #include "Type.h" #include "driverlib/gpio.h" #include "inc/hw_memmap.h" #define #define #define ST7920_CLK_PIN ST7920_CS_PIN ST7920_DI_PIN GPIO_PIN_2 // GPIO 管脚 2 的位表示(0x04) GPIO_PIN_3 // GPIO 管脚 3 的位表示(0x08) GPIO_PIN_5 // GPIO 管脚 5 的位表示(0x20)

//由于外部电平转换电路是反向的,这个程序也作了反向,具体如下!

#define #define

ST7920_CLK_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CLK_PIN, ST7920_CLK_PIN),delay10us(1)) ST7920_CLK_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CLK_PIN, ~ST7920_CLK_PIN),delay10us(1)) ST7920_CS_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CS_PIN, ST7920_CS_PIN),delay10us(1)) ST7920_CS_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CS_PIN, ~ST7920_CS_PIN),delay10us(1)) ST7920_DI_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_DI_PIN, ST7920_DI_PIN),delay10us(1)) ST7920_DI_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_DI_PIN, ~ST7920_DI_PIN),delay10us(1))

#define #define

#define #define

/* 操作接口变量定义 */ extern INT16U buf_lcd_char[4][8]; /* RAM 区域定义 */ #define ST7920_RAM_DDRAM 0 #define ST7920_RAM_IRAM 1 #define ST7920_RAM_CGRAM 2 #define ST7920_RAM_GDRAM 4 /* 接口函数定义 */ void open_st7920(void); void write_st7920(INT8U ram, INT16U addr, INT8U *p_data, INT8U len);

void send_cmd_st7920(INT8U cmd); void open_lcd(void); void write_char_buf(INT8U row, INT8U col, INT8U *pc); void start_logo(void); void lcd(void); #endif (4) delay.c 文件 #include "Type.h" #include "driverlib/sysctl.h" #include "delay.h" extern INT32U TheSysClock;

/****************************************************************************** ******** 函数名: void delay10ms(INT16U time) 功 能: 延时 10ms 说 明: 无 输 入:time 输 出:无 返 回:无 其 他:无 ******************************************************************************* *******/ void delay10ms(INT16U time) { INT16U i; for(i=0;i<time;i++) { delay1ms(10); } } /****************************************************************************** ******** 函数名: void Cpu_Delay100US(INT16U time) 功 能: 延时 100us 说 明: 无 输 入:无 输 出:无 返 回:无 其 他:无

******************************************************************************* *******/ void delay1ms(INT16U time) { INT16U i; for(i=0;i<time;i++) { SysCtlDelay(TheSysClock/3000); } } void delay10us(INT16U time) { INT16U i; for(i=0;i<time;i++) { SysCtlDelay(TheSysClock/300000); } } (5) delay.h 文件 #ifndef _delay_H #define _delay_H

void delay10ms(INT16U time); void delay1ms (INT16U time); void delay10us(INT16U time); #endif (6) Type.h 文件 #ifndef _TYPE_H #define _TYPE_H /* 类型定义 */ typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned short int INT16U; typedef signed short int INT16S; typedef unsigned long int INT32U; typedef signed long int INT32S; typedef float FP32;

/* 无符号 8 位数 */ /* 有符号 8 位数 */ /* 无符号 16 位数 */ /* 有符号 16 位数 */ /* 无符号 32 位数 */ /* 有符号 32 位数 */ /* 单精度浮点数 */

typedef double typedef unsigned char
(2)图片点阵提取

FP64; tBoolean;

/* 双精度浮点数 */

单色 LCD 128*64 液晶显示图片只能是 128*64 像素的,一般提取点阵首先要将图片转换为 128*64 像素, 然后用画图工具 (开始->所有程序->附件->画图) 打开, 将其保存为单色位图, 最后用点阵提取工具提取点阵。

三、 TI LM3S811 板与 LCD128*64 硬件接口连接
我使用的这个屏工作电压是 5V,而 LM3S811 IO 输出电压为 3.3V,所以两者通讯电平不 一致,无法完成通讯,在此为了完成测试,采用万能板手动焊接了个简易电路,原理图为:


相关文章:
Cortex-M3经验谈
具体是这样的: Stellaris 器件内部的 SRAM 的地址是 0x2000.0000,为了减少读-修改-写(RMW) 操作的时间,ARM 在 Cortex-M3 处理器中引入了 bit-banding 技术。...
EFM32 Cortex参考手册
EFM32 Cortex参考手册_工学_高等教育_教育专区。ARM 毕业设计 英文翻译译文EFM32 Cortex-M3 参考手册 1. 简介 1.1 关于此文档 本文档提供了使用 EFM32 微处理...
CortexM3-1300安装使用
CortexM3-1300安装使用_电子/电路_工程科技_专业资料。1. 安装 keil。 2. 只更改 core 一行的路径即可,pack 一行会根据安装路径自行改 变。点下一步安装。 3...
Cortex-M3资料
Cortex-M3资料_信息与通信_工程科技_专业资料。Cortex-M3是一个32位的核,在传统...keil_for_LM3S1138教程 20页 免费 ARM Cortex A8芯片汇总及... 21页 免费 ...
ARM CORTEX-M3 内核架构理解归纳
ARM CORTEX-M3 内核架构理解归纳_计算机硬件及网络_IT/计算机_专业资料。在我看来,Cotex-M3 内核的主要包括:嵌套向量中断控制器(NVIC) ,取值单元,指令译 码器,...
Cortex-M3 32位数据操作指令
Cortex-M3 32位数据操作指令_信息与通信_工程科技_专业资料 暂无评价|0人阅读|0次下载|举报文档 Cortex-M3 32位数据操作指令_信息与通信_工程科技_专业资料。...
STM32 开发入门教程_图文
STM32 开发入门教程_计算机软件及应用_IT/计算机_...在 STM32 的应用中,使用 Cortex-M3 内核的 ...功能非常实用,它的供电和时钟是独立于内核的,可以说...
Cortex-M3寄存器总汇
Cortex-M3中必须为1 3、复位源标识寄存器 RSID(0x400FC180) RSID-地址 0x400FC180 域 [0] 名称 POR 描述上电复位(POR) 信号有效时该位置位。并清零该...
Cortex-M3的优势
ARM Cortex-M3 相比于 ARM 其他系列微控制器,具有以下优势或特点: 1. 三级流水线+分支预测 ARM Cortex-M3 与 ARM7 内核一样,采用适合于微控制器应用的三级...
Cortex M3选型
Cortex M3选型_工学_高等教育_教育专区。ARM芯片型号选择外设: 1.Flash:Flash 闪存是一种不挥发性( Non-Volatile )内存,在没有电流供应的条件下也能 够长久地...
更多相关标签:
cortex m3视频教程 | cortex m3 | cortex m0 m3 m4区别 | cortex m3权威指南 | arm cortex m3 | cortex m3 m4区别 | cortex m3 m4权威指南 | cortexm3 macro.s |