完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
7 个讨论
|
|
感觉很奇怪。之前用5V,STC单片机驱动没有问题的,现在换3.3V,STM32就出现问题了。估计是初始化时序,还在测试调试中!
|
|
|
|
|
|
#define _LCD_DRV_C_
#include "Drv.h" #include "Fmm.h" //---------------------------------------------------------- void Delay(INT16U times) { while(times) { times--; } } //---------------------------------------------------------- void M_Delay(INT16U NOs) { while(NOs) { Delay(200); NOs--; } } //---------------------------------------------------------- //IO输入 void IOInitIn() { GPIO_InitTypeDef InitType; InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAH; InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Init(GPIOB,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAL0; InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_Init(GPIO_LCD_CMD_DATAL0_SELECT,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAL1; InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); GPIO_Init(GPIO_LCD_CMD_DATAL1_SELECT,&InitType); } //IO输出 void IOInitOut() { GPIO_InitTypeDef InitType; InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAH; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Init(GPIOB,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAL0; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_Init(GPIO_LCD_CMD_DATAL0_SELECT,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz; InitType.GPIO_Pin = DATAL1; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); GPIO_Init(GPIO_LCD_CMD_DATAL1_SELECT,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz;//RS InitType.GPIO_Pin = PORT_LCD_RS; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIO_LCD_RS,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz;//RW InitType.GPIO_Pin = PORT_LCD_RW; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIO_LCD_RW,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz;//EN InitType.GPIO_Pin = PORT_LCD_EN; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIO_LCD_EN,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz;//CS1 InitType.GPIO_Pin = PORT_LCD_CS1; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_Init(GPIO_LCD_CS1,&InitType); InitType.GPIO_Speed=GPIO_Speed_50MHz;//CS2 InitType.GPIO_Pin = PORT_LCD_CS2; InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_Init(GPIO_LCD_CS2,&InitType); } //检测忙 void CheckState() { GPIO_WriteBit(GPIO_LCD_RS, PORT_LCD_RS, (BitAction)PIN_LCD_RS_ENABLE); GPIO_WriteBit(GPIO_LCD_RW, PORT_LCD_RW, (BitAction)PIN_LCD_RW_DISABLE); GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_DISABLE); //EN下降沿 IOInitIn(); while(GPIO_ReadInputData(GPIOB) & 0x0100); GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_ENABLE); //EN下降沿 IOInitOut(); } /*写命令到LCD*/ void SendCommandToLCD(INT8U com) { INT16U Tcom; Tcom=com; CheckState();//状态检测LCD是否忙 GPIO_WriteBit(GPIO_LCD_RS, PORT_LCD_RS, (BitAction)PIN_LCD_RS_ENABLE); //向LCD发送命令。RS=0写指令,RS=1写数据 GPIO_WriteBit(GPIO_LCD_RW, PORT_LCD_RW, (BitAction)PIN_LCD_RW_ENABLE);//R/W="L",E="H->L"数据被写到IR或DR //DATA=com; //com :命令 GPIOB->ODR=(GPIOB->ODR & 0xfc0f)|((Tcom<<2)&0xfff3); if(com&0x01) { GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT, DATAL0, (BitAction)PIN_LCD_RW_DISABLE); } else { GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT, DATAL0, (BitAction)PIN_LCD_RW_ENABLE); } if(com&0x02) { GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT, DATAL1, (BitAction)PIN_LCD_RW_DISABLE); } else { GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT, DATAL1, (BitAction)PIN_LCD_RW_ENABLE); } GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_DISABLE);//EN下降沿 GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_ENABLE);//EN下降沿 } /*设置页0Xb8是页的首地址*/ void SetLine(INT8U page) {page=0xb8|page; //1011 1xxx 0<=page<=7设定页地址 --X 0-7,8行为一页64/8=8,共8页 SendCommandToLCD(page); } /*设定显示开始行,0xc0是行首地址*/ void SetStartLine(INT8U startline) {startline=0xc0|startline; //1100 0000 SendCommandToLCD(startline); //设置从哪行开始:0--63,一般从0行开始显示 } /*设定列地址--Y 0-63,0x40为列首地址*/ void SetColumn(INT8U column) {column=column &0x3f; //column最大值为64,输出 0= SendCommandToLCD(column); } /*开关显示,0x3f是开显示,0x3e是关显示*/ void SetOnOff(INT8U onoff) {onoff=0x3e|onoff; //0011 111x,onoff只能为0/1 SendCommandToLCD(onoff); } /*写显示数据*/ void WriteByte(INT8U dat) { INT16U Tcom; Tcom=dat; CheckState();//状态检查,LCD是否忙 GPIO_WriteBit(GPIO_LCD_RS, PORT_LCD_RS, (BitAction)PIN_LCD_RS_DISABLE); //向LCD发送命令。RS=0写指令,RS=1写数据 //RS=0写指令 RS=1写数据 GPIO_WriteBit(GPIO_LCD_RW, PORT_LCD_RW, (BitAction)PIN_LCD_RW_ENABLE);//R/W="L",E="H->L"数据被写到IR或DR////R/W="L",E="H->L"数据被写到IR/DR GPIOB->ODR=(GPIOB->ODR & 0xfc0f)|((Tcom<<2)&0xfff3); if(dat&0x01) { GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT, DATAL0, (BitAction)PIN_LCD_RW_DISABLE); } else { GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT, DATAL0, (BitAction)PIN_LCD_RW_ENABLE); } if(dat&0x02) { GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT, DATAL1, (BitAction)PIN_LCD_RW_DISABLE); } else { GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT, DATAL1, (BitAction)PIN_LCD_RW_ENABLE); }//dat:显示数据 GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_DISABLE);//EN下降沿 GPIO_WriteBit(GPIO_LCD_EN, PORT_LCD_EN, (BitAction)PIN_LCD_EN_ENABLE);//EN下降沿 } /*选择屏幕 0全屏,1左屏 2右屏*/ void SelectScreen(INT8U screen) {switch(screen) { case 0: GPIO_WriteBit(GPIO_LCD_CS1, PORT_LCD_CS1, (BitAction)PIN_LCD_CS1_DISABLE);//全屏 GPIO_WriteBit(GPIO_LCD_CS2, PORT_LCD_CS2, (BitAction)PIN_LCD_CS2_DISABLE); break; case 1: GPIO_WriteBit(GPIO_LCD_CS1, PORT_LCD_CS1, (BitAction)PIN_LCD_CS1_DISABLE);//左屏 GPIO_WriteBit(GPIO_LCD_CS2, PORT_LCD_CS2, (BitAction)PIN_LCD_CS2_ENABLE); break; case 2: GPIO_WriteBit(GPIO_LCD_CS1, PORT_LCD_CS1, (BitAction)PIN_LCD_CS1_ENABLE);//右屏 GPIO_WriteBit(GPIO_LCD_CS2, PORT_LCD_CS2, (BitAction)PIN_LCD_CS2_DISABLE); break; } } //初始化液晶 void LcdDrvInit(void) { //初始化端口 IOInitOut(); //复位液晶 //延时 //初始化变量 memset(&gLcdDrvData,0,sizeof(LCD_DRV_DATA_STRUCT)); } //初始化液晶端口 void LcdDrvPortInit(void) { GPIO_InitTypeDef InitType; InitType.GPIO_Speed=GPIO_Speed_50MHz; //置输出上拉 InitType.GPIO_Pin = DATAH; InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Init(GPIOB,&InitType); } //延时 void LcdDrvDelay(INT16U DelayTime) { for(;DelayTime>0;DelayTime--); } //加载对比度 void LcdDrvLoadContrastValue(INT8U ContrastValue) { //对比度值越界 #if 0 if(ContrastValue>=CONTRAST_MAX_VALUE) return; //发送对比度调节命令 LcdDrvSendLcdData(SEND_LCD_COMMAND, DISPLAY_COMMAND_SET_CONTRAST_MODE); //发送对比度调节数据 LcdDrvSendLcdData(SEND_LCD_COMMAND, ContrastValue); #endif } //发送液晶数据 void LcdDrvSendLcdData(LCD_DRV_SEND_CMD_DATA_SELECT_Def SelectType, INT8U SendData) { #if 0 INT8U i,DelayNop; //选择发送类型 switch(SelectType) { //发送指令 case SEND_LCD_COMMAND: GPIO_WriteBit(GPIO_LCD_CMD_DATA_SELECT, PORT_LCD_CMD_DATA_SELECT, (BitAction)PIN_LCD_CMD_SELECT); break; //发送数据 case SEND_LCD_DATA: GPIO_WriteBit(GPIO_LCD_CMD_DATA_SELECT, PORT_LCD_CMD_DATA_SELECT, (BitAction)PIN_LCD_DATA_SELECT); break; default: return; } //片选 GPIO_WriteBit(GPIO_LCD_CHIP_SELECT, PORT_LCD_CHIP_SELECT, (BitAction)PIN_LCD_CHIP_SELECT_ENABLE); //发送 for(i=0;i<8;i++) { if((SendData&0x80)==0x80) GPIO_WriteBit(GPIO_LCD_SOUT, PORT_LCD_SOUT, (BitAction)PIN_LCD_SOUT_HIGH); else GPIO_WriteBit(GPIO_LCD_SOUT, PORT_LCD_SOUT, (BitAction)PIN_LCD_SOUT_LOW); //延时 DelayNop=DelayNop;DelayNop=DelayNop; DelayNop=DelayNop;DelayNop=DelayNop; //产生时钟上升沿 GPIO_WriteBit(GPIO_LCD_SCLK, PORT_LCD_SCLK, (BitAction)PIN_LCD_SCLK_HIGH); //延时 DelayNop=DelayNop;DelayNop=DelayNop; DelayNop=DelayNop;DelayNop=DelayNop; //恢复时钟信号低电平 GPIO_WriteBit(GPIO_LCD_SCLK, PORT_LCD_SCLK, (BitAction)PIN_LCD_SCLK_LOW); SendData<<=1; } //撤消片选 GPIO_WriteBit(GPIO_LCD_CHIP_SELECT, PORT_LCD_CHIP_SELECT, (BitAction)PIN_LCD_CHIP_SELECT_DISABLE); #endif } //显示半角汉字/数字/字母 void Displayen(INT8U ss,INT8U page,INT8U column,INT8U *number) {INT8U i;//选屏参数,page选页参数,column选列参数,number选第几汉字输出 SelectScreen(ss); column=column&0x3f; SetLine(page); //写上半页 SetColumn(column); for(i=0;i<8;i++) {WriteByte(number[i]);} SetLine(page+1); //写下半页 SetColumn(column); for(i=0;i<8;i++) {WriteByte(number[i+8]);} } /*显示全角汉字*/ void Display(INT8U ss,INT8U page,INT8U column,INT8U *number) {INT8U i; //选屏参数,page选页参数,column选列参数,number选第几汉字输出 SelectScreen(ss); column=column&0x3f; SetLine(page); //写上半页 SetColumn(column); //控制列 for(i=0;i<16;i++) //控制16列的数据输出 {WriteByte(number[i]);}//i+32*number汉字的前16个数据输出 SetLine(page+1); //写下半页 SetColumn(column); //控制列 for(i=0;i<16;i++) //控制16列的数据输出 {WriteByte(number[i+16]);}//i+32*number+16汉字的后16个数据输出 } //液晶驱动 void LcdDrvLoadLcdData(INT8U lin, INT8U column,INT8U *LcdData, INT8U Len) { INT8U ss=0; //×?·? if(Len==16) { column=column*8; //if(column<8) SelectScreen(0); //如果列队<8(0,1,2,3,4,5,6,7)则写在第一屏上面 if(column<64) { ss=1; } else { ss=2; column=column-64; } lin=lin<<1; Displayen(ss,lin,column,LcdData); } if(32==Len) { column=column*16; if(column<64) { ss=1; } else { ss=2; column=column-64; } lin=lin<<1; Display(ss,lin,column,LcdData); } } /*------------------显示边框-------------------------------*/ void frame() { INT8U i; SelectScreen(2); for (i = 0;i < 8;i++) { SetLine( i); //共8页 SetColumn( 31); //最后一页 WriteByte(0xff); //ff表示每页的8行全亮 //#define Page_Add 0xb8 //起始页地址 //#define Start_Line 0xc0 //起始行地址 } } /*清屏screen: 0-全屏,1-左屏,2-右屏*/ void ClearScreen(INT8U screen) {INT8U i,j; SelectScreen(screen); for(i=0;i<8;i++) //控制页数0-7,共8页 {SetLine(i); SetColumn(0); for(j=0;j<64;j++) //控制列数0-63,共64列 {WriteByte(0x00);} //写点内容,列地址自动加1 } } /*初始化LCD*/ void init_lcd() { CheckState(); SelectScreen(0); SetOnOff(0); //关显示 SelectScreen(0); SetOnOff(1); //开显示 SelectScreen(0); ClearScreen(0);//清屏 SetStartLine(0); //开始行:0 } |
|
|
|
|
|
|
|
|
|
|
|
STC单片机直接用的12M晶振,选用的是传统51单片机的指令周期,应该是1M STM32也是选用的12M晶振,RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK /* 设置低速APB2时钟,这个时钟从AHB时钟分频而来分频系数为1,2,4,8,16 */ RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK /* 设置低速APB1时钟,这个时钟从AHB时钟分频而来分频系数为1,2,4,8,16 */ RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2 各种分频都试过还是不行。。。。 |
|
|
|
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
STM32CUBEMX(13)--SPI,W25Q128外部Flash移植
676 浏览 0 评论
OV7670摄像头使用串口发送数据到另一个板子上的lcd,出现花屏
1459 浏览 1 评论
788 浏览 0 评论
705 浏览 0 评论
STM32CUBEMX(12)--IIC,12864OLED(0.96寸)移植
805 浏览 0 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-10-4 05:14 , Processed in 0.807032 second(s), Total 51, Slave 43 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号