高级会员
 
主题
帖子
积分2691
阅读权限30
注册时间2012-10-23
最后登录1970-1-1
在线时间 小时
|
除了stm32内置模块的代码要重写,外部模块代码基本上不要重写,只要做一点修好即可。
如,lcd1602驱动,修改一点就可以了
//==========================================================================
// 项目:LCD1602 四线驱动程序
// 设计要点:
// LCD1602 的运行速度慢,而单片机运行的速度快,因此容易因为速度不
// 匹配造成调试失败。因此,调试之前应准确测试lcd_delay() 延时函数
// 准确的延时量,如果不能满足注释中的要求,则应调整循次数。每步操
// 作所需的延时量,按照数据手册指标指行,同时留下足够的时间余量。
// 硬件连接:
// 至少需要9条线,电源线2条,7条信号线。信号线详见程序中的接口定义。
// 清注意对LCD1602对比度的调节,否则无显示。
// 设计:许剑伟,于莆田,2010.12编写,2012.12改写为stm32程序
//==========================================================================
#define lcd_RS(v) lcd_Wbit(GPIOB,GPIO_Pin_13,v) //数据命令控制位,0命令1数据
#define lcd_RW(v) lcd_Wbit(GPIOB,GPIO_Pin_0, v) //读写位,0写1读
#define lcd_EN(v) lcd_Wbit(GPIOB,GPIO_Pin_12,v) //使能位,下降沿触发
#define lcd_D4(v) lcd_Wbit(GPIOB,GPIO_Pin_1, v) //数据端口D4
#define lcd_D5(v) lcd_Wbit(GPIOB,GPIO_Pin_2, v) //数据端口D5
#define lcd_D6(v) lcd_Wbit(GPIOB,GPIO_Pin_10,v) //数据端口D6
#define lcd_D7(v) lcd_Wbit(GPIOB,GPIO_Pin_11,v) //数据端口D7
//==========================================================================
void lcd_Wbit(GPIO_TypeDef* GPIOx, u16 GPIO_Pin, u8 v){ //位输出
if(v) GPIOx->BSRR = GPIO_Pin;
else GPIOx->BRR = GPIO_Pin;
}
//==========================================================================
void lcd_delay(int n){ //LCD专用延时函数
//32MHz钟频下,约循环3000次延迟1毫秒
int i,j;
if(n<0) { for(i=0;i<100;i++); return; } //10us
if(n== 0) { for(i=0;i<500;i++); return; } //50us
for(;n;n--){ for(j=0;j<10000;j++); } //n毫秒
}
//==========================================================================
void lcd_B(char f, u8 c, char t){ //控制四线式接口LCD的7个脚
//f=0写命令字, f=1写RAM数据, f=2读地址(或读忙), f=3读RAM数据
lcd_EN(0);
lcd_RS(f%2);
lcd_RW(f/2%2);
//移入高四位
lcd_D4( c&16 );
lcd_D5( c&32 );
lcd_D6( c&64 );
lcd_D7( c&128 );
lcd_EN(1); lcd_delay(-1); lcd_EN(0); //使能脉冲
if(f==4) { lcd_delay(t); return; }
//移入低四位
lcd_D4(c&1);
lcd_D5(c&2);
lcd_D6(c&4);
lcd_D7(c&8);
lcd_EN(1); lcd_delay(-1); lcd_EN(0); //使能脉冲
lcd_delay(t); //不同的命令,响应时间不同,清零命令需要2ms
}
//==========================================================================
void lcd_init(){ //LCD1602 初始化
//启动四线模式须执行9个步骤,初始化所须耗时较长,约65ms,时限不可减
lcd_delay(20); //启动lcd之前须延时大于15ms,直到VDD大于4.5V
lcd_B(4, 0x30, 9); //置8线模式,须延时大于4.1ms
lcd_B(4, 0x30, 5); //置8线模式,须延时大于100us
lcd_B(4, 0x30, 5); //置8线模式,手册中未指定延时
lcd_B(4, 0x20, 5); //进入四线模式
lcd_B(0, 0x28, 5); //四线模式双行显示
lcd_B(0, 0x0C, 5); //打开显示器
lcd_B(0, 0x80, 5); //RAM指针定位
lcd_B(0, 0x01, 5); //启动清屏命初始化LCD
}
//==========================================================================
//=========================几个功能常用函数=================================
void lcd_cls() { lcd_B(0, 0x01+0, 2); } //清屏
void lcd_cur0() { lcd_B(0, 0x0C+0, 0); } //隐藏光标
void lcd_goto1(u8 x){ lcd_B(0, 0x80+x, 0); } //设置DDRAM地址,第1行x位
void lcd_goto2(u8 x){ lcd_B(0, 0xC0+x, 0); } //设置DDRAM地址,第2行x位
void lcd_putc(u8 d) { lcd_B(1, 0x00+d, 0); } //字符输出
void lcd_puts(u8 *s){ for(; *s; s++) lcd_B(1,*s,0); } //字串输出
#define digW 4 //数字显示位数宏
void lcd_putp(float a,float b,char bo,char n, float qmin){ //带单位显示复数,n是单位下限,qmin是最小位权值(用于限定有效数字)
char dwB[] = {'p','n','u','m',' ','k','M','G'}; //单位表
char i,j, c=0, h=digW-1, fh[2]={' ','+'};
long d,q,qm,Q=1; //最高位权
float f,g=1;
if(a<0) fh[0] = '-', a = -a;
if(b<0) fh[1] = '-', b = -b;
if(a>b) f = a; else f = b;
for(i=1;i<digW;i++) Q *= 10;
for(i=0;i<3;i++){ if(f*g >= 1000) g/=1000, c++; } //以3位为单位移动小数点,右移
for(i=0;i<n;i++){ if(f*g < 1) g*=1000, c--; } //以3位为单位移动小数点,左移
for(i=1;i<digW && f*g<Q;i++) g*=10,h--; //继续移动小数点,使之满字
qm = g*qmin;
for(i=0;i<2;i++){
if(i) d = b*g+0.5; //取出实部
else d = a*g+0.5; //取出虚部
if(qm) d+=qm/2, d-=d%qm;//去除小于qmin的尾数
q = Q;
lcd_putc(fh); //显示符号
for(j=0; j<digW; j++){ //数字输出
lcd_putc(d/q+48); //数字
if(j==h) lcd_putc('.');//小数点
d %= q, q /= 10;
}
if(!bo) break; //不显示虚部
}
lcd_putc(dwB[c+4]); //单位
}
void lcd_putf(float a, char n, float qmin) //带单位显示浮点数,n是单位下限
{ lcd_putp(a,0,0,n,qmin); }
void lcd_int(int a,char w){ //定宽显示整数
char i=0, s[5] = {' ',' ',' ',' ',' '};
if(a<0) { a=-a; lcd_puts("-"); }
else lcd_puts(" ");
do{
s[i++] = a%10+48;
a /= 10;
}while(a);
for(;w;w--) lcd_putc(s[w-1]);
} |
|