参考STM32数据手册可知,工作电压为3.3V的STM32F103的I/O口可以驱动5V的外设器件。但并不是所有I/O都有该功能,条件是必须符合手册中引脚定义的I/O电平具备“FT”项的,见《数据手册》表5。故决定此次DIY进程的LCD选用1片5V工作电压的12864液晶模块来应用,以体验STM32F103在3.3V工作条件下驱动5V器件的能力。分析ARM开发板的I/O扩展口,发现GPIO_D的PIN8-PIN15同在一组排针顺序引出,用它来做LCD的数据口正合适,顺便PD口上方的PB13-PB15和下方的PG2-PG4刚好用做控制口。接法见图1。
关于12684LCD的源代码网上到处都可以Download,你可以自己移植一下就OK了。因篇幅关系,我就不全部上传了,只上传部分供参考。比如在判断LCD忙的代码段,我用了直接寄存器操作方式来改变GPIOD_15的输入、输出工作模式,这样运行速度比用库操作方式快,能满足LCD12864的时序要求。
主函数:
#include "stm32f10x.h"
#include "LCD.C"
u16 speed=2000;
u16 Count=0;
RCC_ClocksTypeDef RCC_ClockFreq;
void GPIO_Configuration(void) ;
void Delay(u16 speed);
int main(void)
{
SystemInit();
RCC_GetClocksFreq(&RCC_ClockFreq);
GPIO_Configuration();
LcdInit();
Clr_Scr();
byte_disp(1,1,'A');
byte_disp(1,2,'R');
byte_disp(1,3,'M');
word_disp(0,2,Kai);
word_disp(0,3,Fa);
word_disp(0,4,Ban);
byte_disp(1,13,'D');
byte_disp(1,14,'I');
byte_disp(1,15,'Y');
byte_disp(3,1,'S');
byte_disp(3,2,'T');
byte_disp(3,3,'M');
byte_disp(3,4,'3');
byte_disp(3,5,'2');
byte_disp(3,6,'F');
byte_disp(3,7,'1');
byte_disp(3,8,'0');
byte_disp(3,9,'3');
byte_disp(3,11,'3');
byte_disp(3,12,'.');
byte_disp(3,13,'3');
byte_disp(3,14,'v');
word_disp(4,1,Qu);
word_disp(4,2,Dong);
byte_disp(5,8,'5');
byte_disp(5,9,'V');
byte_disp(5,11,'L');
byte_disp(5,12,'C');
byte_disp(5,13,'D');
byte_disp(7,1,'W');
byte_disp(7,2,'e');
byte_disp(7,3,'n');
byte_disp(7,4,'y');
byte_disp(7,5,'a');
byte_disp(7,6,'n');
byte_disp(7,7,'g');
byte_disp(7,8,'z');
byte_disp(7,9,'e');
byte_disp(7,10,'n');
byte_disp(7,11,'g');
word_disp(6,5,Jin);
word_disp(6,6,Cheng);
while (1)
{ ;
}
}
//-----------------------------
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
GPIO_SetBits(GPIOD, GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11
|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
GPIO_SetBits(GPIOG, GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_SetBits(GPIOB, GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
直接寄存器操作函数
//------------------------
//函数名:CheckState()
//功能:等待LCD不忙
//-------------------
void CheckState()
{
GPIOD->CRH &=0X0FFFFFFF;
GPIOD->CRH |=0X40000000;
RS_L;
RW_H;
EN_H;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_15)) ;
EN_L;
GPIOD->CRH &=0X0FFFFFFF;
GPIOD->CRH |=0X10000000;
}
显示效果见图2
ARM DIY进程3:超声波测距仪
通过测距仪功能的实现学习了定时器的设置,学习了通过外部中断捕获脉冲宽度。
原计划利用stm32 捕获PWM周期和占空比来实现该功能,这要利用到TIMx的TI2FP2和TI1FP1资源。见图1。但
在实现过程中发现开发板将超声波ECHO端连接在PB1。查手册可知PB1连接TIM3的通道4,使用的是TI3FP3和
TI4FP4资源,而STM32的PWM输入模式只能使用TI2FP2和TI1FP1。浪费了不少时间,走了弯路。发现在开发板上现
有硬件连接状态下用stm32 捕获PWM周期和占空比来实现超声波测距功能无法实现。(见《STM32F参考手册》截
图中红圈说明)。
改用外部中断方案,PB1口设为上拉输入,外部中断模式,下降及上升沿触发中断,连接到1号中断线,中断入口为EXTI1_IRQn。在PB0产生20uS触发信号后,置EXTI1上升沿中断,等待回波上升沿到来。进入中断后清TIM3零计数器并设EXTI1为下将沿中断。在下降沿中断到来时读出距离值。
我使用的HC-SR04模块工作电压是5V,开发板上对其供电是3.3V,故实际使用中测量距离大打折扣,最远只能测到0.67米,最近测到0.22米。
图1,最短测距
附部分代码:
int main(void)
{ u8 a,b,c;
SystemInit();
RCC_GetClocksFreq(&RCC_ClockFreq);
GPIO_Configuration();
TIM_Configuration();
TestLCDS();
EXTI->EMR &= ~0X02;
while (1)
{
GPIOB->ODR |=0X01;
Delay(1);
GPIOB->ODR &=~0X01;
EXTI->EMR |=0X02;
Delay(2000);
a = DutyCycle%10000/1000;
b = DutyCycle%1000/100;
c = DutyCycle%100/10;
byte_disp(6,7,a+'0');
byte_disp(6,8,'.');
byte_disp(6,9,b+'0');
byte_disp(6,10,c+'0');
}
}
//与EXTI相关的代码
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//定时器配置
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 320;
TIM_TimeBaseStructure.TIM_ClockDivision = 100;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_Cmd(TIM3, ENABLE);
//中断代码
void EXTI1_IRQHandler(void)
{ if(GPIOB->IDR & 0x02)
{
EXTI->RTSR &=~0X2;
EXTI->FTSR |=0X2;
TIM3->CNT =0;
}
else
{
EXTI->RTSR |=0X2;
EXTI->FTSR &=~0X2;
DutyCycle = TIM3->CNT;
EXTI->EMR &=~0X02;
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
ARM DIY进程4:ADC,DMA
采用DMA中断方式传输ADC数据,练习了ADC和DMA的配置方法。在LCD显示屏上显示了由片内温度传感器转换出的芯片温度值,通过外接电位器,将0-3.3V直流电压加到PB1口(ADC1的通道9),在LCD屏幕上显示转换的电压值。
刚开始,ADC转换结果一直为0XFFF,反复查看修改代码没有结果,后来测量芯片有关引脚电压,发现VREF+始终为零,检查PCB板最后发现VREF+是由PCB板背面的VDDA经R62到一过孔连接到PCB板上面STM32F10332脚的,仔细检查发现过孔的孔中断裂致使VREF+丢失,用一细铜丝穿过这个过孔,两面焊接,终于得到正确的ADC转换结果。
图1 ADC转换通道16的芯片温度值
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |