2024年1月3日发(作者:yaris l 致炫报价及图片)
第一部分 准备篇
第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日处理完毕。(更多详情,敬请访问:/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库以及代码示例。如欲了解更多详情,敬请访问:/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工具厂商提供可简化开发的完整源代码、文档以及多种评估工具的选择;
??如欲了解更多信息或购买套件,敬请访问:/lm3s9B90evalkits-pr 或/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软件与评估工具;
??如欲了解更多详情或购买套件,敬请访问:/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欧姆外部扬声器;
??如欲了解更多详情或购买套件,敬请访问:/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, PWM_OUT_0, 0); //设置PWM的脉冲宽度
PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, 1);
PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, 12000);
PWMPulseWidthSet(PWM_BASE, PWM_OUT_3, 23998);
PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, 23999);
PWMPulseWidthSet(PWM_BASE, PWM_OUT_5, 24000);
PWM频率设置成了250Hz,对应于24000个时钟周期,当脉宽宽度设置成0、23999、24000,PWM出来都是高电平,如下图所示:MDK自带的Logic Analyzer
(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行左右,及其短小,但很好用
/?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
#include
#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_GPIOB
SYSCTL_PERIPH_GPIOE | SYSCTL_PERIPH_GPIOD);
//
使能KEY所在的GPIO端口
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); //使能KEY所在的GPIO端口
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4); //设置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_STOP_ONE
UART_CONFIG_PAR_NONE);
UARTEnable(UART0_BASE);
}
void put(const char *x)
{
while(*x!=\'0\')
{
UARTCharPut(UART0_BASE,*(x++));
}
}
void wellcome()
{
put(\"hello,21ic!rn\");
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(\"℃rn\");
}
// 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
#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); /* Function Set GD Disable */
send_cmd_st7920(0x30); /* Function Set RE=0 */
addr_ram = (INT8U)addr;
addr_ram &= 0x3F;
addr_ram |= 0x80;
send_cmd_st7920(addr_ram); /* Set DDRAM address */
break;
case ST7920_RAM_IRAM:
send_cmd_st7920(0x34); /* Function Set RE=1 */
addr_ram = (INT8U)addr;
addr_ram &= 0x0F;
addr_ram |= 0x40;
send_cmd_st7920(addr_ram); /* Set SEGRAM address */
break;
case ST7920_RAM_CGRAM:
send_cmd_st7920(0x30); /* Function Set RE=0 */
addr_ram = (INT8U)addr;
addr_ram &= 0x3F;
addr_ram |= 0x40;
send_cmd_st7920(addr_ram); /* Set CGRAM address */
break;
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 { /* #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] = (pc[2*i+2]<<8); } #endif */ buf_lcd_char[r][k] = pc[2*i]; 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[] LCD文字显示缓冲区 输出:无 **************************************************************************************/ void lcd(void) { INT8U static ddram_row = 0; /* 刷新行号,每次刷新一行 */ 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] <= 125 && buf_lcd_char[lcd_row][lcd_col] >= 32 ) { buf_lcd_char[lcd_row][lcd_col] += 0xA380; } } } /* 选择行 */ switch (ddram_row) { case 0: /* LCD缓冲区 0行对应DDRAM 0行 */ lcd_row = 0; break; case 1: /* LCD缓冲区 1行对应DDRAM 2行 */ lcd_row = 2; break; case 2: /* LCD缓冲区 2行对应DDRAM 1行 */ lcd_row = 1; break; case 3: /* LCD缓冲区 3行对应DDRAM 3行 */ lcd_row = 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; } } 三、(3) st7920.h文件 #ifndef _12864_H #define _12864_H #include \"Type.h\" #include \"driverlib/gpio.h\" #include \"inc/hw_memmap.h\" #define ST7920_CLK_PIN GPIO_PIN_2 // GPIO管脚2的位表示(0x04) #define ST7920_CS_PIN GPIO_PIN_3 // GPIO管脚3的位表示(0x08) #define ST7920_DI_PIN GPIO_PIN_5 // GPIO管脚5的位表示(0x20) //由于外部电平转换电路是反向的,这个程序也作了反向,具体如下! #define ST7920_CLK_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CLK_PIN, ST7920_CLK_PIN),delay10us(1)) #define ST7920_CLK_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CLK_PIN, ~ST7920_CLK_PIN),delay10us(1)) #define ST7920_CS_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CS_PIN, ST7920_CS_PIN),delay10us(1)) #define ST7920_CS_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_CS_PIN, ~ST7920_CS_PIN),delay10us(1)) #define ST7920_DI_0() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_DI_PIN, ST7920_DI_PIN),delay10us(1)) #define ST7920_DI_1() (GPIOPinWrite(GPIO_PORTA_BASE, ST7920_DI_PIN, ~ST7920_DI_PIN),delay10us(1)) /* 操作接口变量定义 */ 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
更多推荐
程序,控制,设置,输出
发布评论