stm32并口驱动12864,求大神看看我的程序错在哪了?编译通过但是屏幕上没显示~搞了两天了,头疼死我了、

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32并口驱动12864,求大神看看我的程序错在哪了?编译通过但是屏幕上没显示~搞了两天了,头疼死我了、相关的知识,希望对你有一定的参考价值。

12864.c文件

#include"stm32f10x_lib.h"
#include"delay.h"
#include"12864.h"
GPIO_InitTypeDef GPIOStru;//定义用于定义所有引脚为输出的变量

void port_init(void)

IOInitOut();
GPIO_SetBits(DisIO,RST);

void IOInitOut(void) //端口输出初始化

RCC_APB2PeriphClockCmd(DisClk,ENABLE);
GPIOStru.GPIO_Mode=GPIO_Mode_Out_PP;//推挽式输出
GPIOStru.GPIO_Speed=GPIO_Speed_50MHz;
GPIOStru.GPIO_Pin=Data|RS|RW|EN|PSB|RST;
GPIO_Init(DisIO,&GPIOStru);


void IOInitIn(void) //端口输入初始化

RCC_APB2PeriphClockCmd(DisClk,ENABLE);
GPIOStru.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入浮空
GPIOStru.GPIO_Speed=GPIO_Speed_50MHz;
GPIOStru.GPIO_Pin=Data;
GPIO_Init(DisIO,&GPIOStru);


void WaitBusy(void) //等待12864忙状态结束

IOInitIn();
GPIO_ResetBits(DisIO,RS);
GPIO_SetBits(DisIO,RW);
GPIO_SetBits(DisIO,EN);
while(GPIO_ReadInputData(DisIO) & 0x0080); //只要位7的值,位7是忙标志位。
GPIO_ResetBits(DisIO,EN); //EN = 0;
IOInitOut(); //把所有引脚定义为输出。

void WriteCmd(u8 cmd)

WaitBusy();
GPIO_ResetBits(DisIO,RS);
GPIO_ResetBits(DisIO,RW);
GPIO_SetBits(DisIO,EN);
DisIO->ODR=((DisIO->ODR&0XFF00)|cmd);
delay_ms(5);
GPIO_ResetBits(DisIO,EN);

void WriteData(u8 data)

WaitBusy();
GPIO_SetBits(DisIO,RS);
GPIO_ResetBits(DisIO,RW);
GPIO_SetBits(DisIO,EN);
DisIO->ODR=((DisIO->ODR & 0xff00)|data);
delay_ms(5);
GPIO_ResetBits(DisIO,EN);

void Init12864(void) //初始化 12864 和要用到的 STM 32 的引脚。


GPIO_SetBits(DisIO,PSB); //令PSB=1,设置为并行数据模式。
delay_ms(5);
WriteCmd(0x30); //选择基本指令集,和,8位数据模式。
delay_ms(5);
WriteCmd(0x0c); //开显示,无游标,不反白.
delay_ms(5);
WriteCmd(0x01); //清除显示,并将 DDRAM 的地址计数器 AC 设为 00H.
delay_ms(5);
WriteCmd(0x06); //设置,外部读写数据后,地址记数器 AC 会自动加 1。
delay_ms(5);
WriteCmd(0x80); //将 DDRAM 地址计数器 AC 设为 0.
delay_ms(5);

// GPIOC->BSRR=0xffff;

void Disp_HZ(u8 addr,u8 *hz)

WriteCmd(addr);
// delay_ms(5);
while(*hz!='\0')

WriteData(*hz);
hz++;
//delay_ms(5);

参考技术A 我有51的程序,可供参考。
#include "lcd12864.h"
#include "ziku.h"
#include <string.h>

static void delay(uint j) //延时

uchar i;
for(; j!=0; j--)
for(i=0; i<100; i++);

void busy(void)

uchar i;
for(i=0;i<50;i++)
_nop_();

void wdata(uchar wdata)

busy(); //忙提示
LCD_RW=0;
LCD_DI=1;
P0=wdata;

LCD_EN=0;
LCD_EN=1;
LCD_EN=0;


void wcode(uchar wcode)

busy();
LCD_RW=0;
LCD_DI=0;

P0=wcode;

LCD_EN=0;
LCD_EN=1;
LCD_EN=0;


void subinit()

delay(10);
wcode(0xc0);//设置显示初始行


//设置显示位置
void setxy(uchar x,uchar y)

if ((y>=0)&(y<=63))

LCD_CSA=0;
LCD_CSB=1;

else //if (y<=127)

LCD_CSA=1;
LCD_CSB=0;

wcode(0x40|(y%64));
wcode(0xb8|x);
P0=0xff;


void wdram(uchar x,uchar y,uchar dd)

setxy(x,y);
wdata(dd);

P0=0xff;
LCD_CSA=1;
LCD_CSB=1;


//复位.
void Lcd_RST(void)

//rst=0;
LCD_REST=0;
delay(50);
LCD_REST=1;
Lcd_Clear(0,7,0,128);
wcode(0x3f);//开显示


//LCD初始化
void Lcd_Init(void)

LCD_POR=0;

Lcd_RST();
LCD_CSA=0;
LCD_CSB=1;

wcode(0x3e);subinit();

LCD_CSA=1;
LCD_CSB=0;
wcode(0x3e);subinit();
Lcd_Clear(0,7,0,128);

LCD_CSA=0;
LCD_CSB=1;
wcode(0x3f);//开显示

LCD_CSA=1;
LCD_CSB=0;
wcode(0x3f);//开显示


void Lcd_On(void)


LCD_CSA=0;
LCD_CSB=1;
wcode(0x3f);//开显示

LCD_CSA=1;
LCD_CSB=0;
wcode(0x3f);//开显示


//LCD 清显示屏
void Lcd_Clear(uchar StartLine,uchar StopLine,uchar StartRow,uchar StopRow)

uchar x,y;
for(x=StartLine; x<StopLine+1; x++)

for(y=StartRow; y<StopRow; y++)

wdram(x,y,0);




//显示一个汉字
void Lcd_DispOneChar(uchar x,uchar y,uchar * hz,uchar disp_mode,uchar Width)

uchar i;
for(i=0; i<Width; i++)

if(disp_mode==WHITE)

wdram(x,y+i,*(hz+i));
wdram(x+1,y+i,*(hz+Width+i));

else

wdram(x,y+i,0xff-*(hz+i));
wdram(x+1,y+i,0xff-*(hz+Width+i));



if(Width==12)

for(i=12; i<14; i++)

if(disp_mode==WHITE)

wdram(x,y+i,0);
wdram(x+1,y+i,0);

else

wdram(x,y+i,0xff);
wdram(x+1,y+i,0xff);



for(i=1; i<4; i++)

if(disp_mode==WHITE)

wdram(x,y-i,0);
wdram(x+1,y-i,0);

else

wdram(x,y-i,0xff);
wdram(x+1,y-i,0xff);





void Lcd_Disp_String(uchar x,uchar y,char *pString,uchar disp_mode)

uchar i,j;
uchar LineDispCode[16];
//strlen(),为字符串长度测量。
memset(LineDispCode,0,16); //清零数组
strcpy(LineDispCode,pString); //字符串之间的相互复制。
for(i=0; i<strlen(pString); i++)

LineDispCode[i]=*(pString+i);


i=0;
while(LineDispCode[i]!=0)

if(LineDispCode[i]>=0xA0)

//显示的是汉字
for(j=0; j<ZIMO_NUM; j++)

if(GB_12[j].Index[0]==LineDispCode[i] &&
GB_12[j].Index[1]==LineDispCode[i+1])

//显示的是汉字
Lcd_DispOneChar(x,y,GB_12[j].Msk,disp_mode,12);
y+=16;
break;


i+=2;

else

//显示的是ASCII编码
for(j=0; j<ASC_NUM; j++)

if(ASC_12[j].Index==LineDispCode[i])

//显示的是汉字
Lcd_DispOneChar(x,y,ASC_12[j].Msk,disp_mode,8);
y+=8;
break;


i++;


if(i>=16)

break;




//显示数字.
void Lcd_Disp_OneNum(uchar x,uchar y,uchar num,uchar disp_mode)

switch(num)

case 0:Lcd_Disp_String(x,y,"0",disp_mode);break;
case 1:Lcd_Disp_String(x,y,"1",disp_mode);break;
case 2:Lcd_Disp_String(x,y,"2",disp_mode);break;
case 3:Lcd_Disp_String(x,y,"3",disp_mode);break;
case 4:Lcd_Disp_String(x,y,"4",disp_mode);break;
case 5:Lcd_Disp_String(x,y,"5",disp_mode);break;
case 6:Lcd_Disp_String(x,y,"6",disp_mode);break;
case 7:Lcd_Disp_String(x,y,"7",disp_mode);break;
case 8:Lcd_Disp_String(x,y,"8",disp_mode);break;
case 9:Lcd_Disp_String(x,y,"9",disp_mode);break;
default: break;


//显示二位数。
void Disp_2num(uchar x,uchar y,uchar num,uchar disp_mode)

uchar ch[2];
ch[0]=num%10;
ch[1]=num/10;
Lcd_Disp_OneNum(x,y,ch[1],disp_mode);
Lcd_Disp_OneNum(x,y+8,ch[0],disp_mode);


//*****************************************************
//显示三位数。
void Disp_3num(uchar x,uchar y,uint num,uchar disp_mode)

uchar ch[2];
ch[0]=num/100;
ch[1]=num%100;
if(ch[0])
Lcd_Disp_OneNum(x,y, ch[0],disp_mode);
else
Lcd_Disp_String(x,y," ",disp_mode);
Disp_2num(x,y+8, ch[1],disp_mode);


//*****************************************************
//显示四位数。
void Disp_4num(uchar x,uchar y,uint num,uchar disp_mode)

uchar ch[4],tmp;
tmp=num/100;
ch[0]=tmp/10;
ch[1]=tmp%10;

tmp=num%100;
ch[2]=tmp/10;
ch[3]=tmp%10;

Lcd_Disp_OneNum(x,y,ch[0],disp_mode);
Lcd_Disp_OneNum(x,y+8,ch[1],disp_mode);
Lcd_Disp_OneNum(x,y+16,ch[2],disp_mode);
Lcd_Disp_OneNum(x,y+24,ch[3],disp_mode);


void Lcd_DispIco2(uchar x,uchar y,uchar *pIco)//显示老肯图标

uchar i,j;
for(i=0; i<4; i++)

for(j=0; j<32; j++)

wdram(x+i,y+j,*pIco);
pIco++;



//*****************************************************
//显示多位数。 disp_mode&0x10==1时,进行即每位都显示,否则大于0的位置不显示。
void Disp_NumGB16(uchar x,uchar y,ulong Data,uchar num,uchar disp_mode)

uchar idata ch=0,i,tmp;
for(i=0;i<num;i++)

tmp=Data%10;
Data/=10;
if((disp_mode&0x10)||tmp>0||Data>0||num<=2)
Lcd_Disp_OneNum(x,y+(num-i-1)*8,tmp,disp_mode%10);
else
Lcd_Disp_String(x,y+(num-i-1)*8," ",disp_mode%10);

参考技术B 你的电平输出是对的么?12864好像是5V电压驱动的吧?追问

3.3V也可以的,之前用msp430驱动12864就是3.3V的。

追答

delayms()函数跟CPU频率相关,你这个函数是delay5Ms么?

追问

是5ms啊 ,还用示波器测的 很准确

stm32编程问题,状态机,求大神指导,初学者,主要是switch语句后面的变量取值不明白

状态机的程序中,如果用到switch语句,那后面的变量没有赋初值,我们应该转向哪一个case语句啊,程序见下方,由于程序太长,我就把大概意思写上了。。。。。
typedef enum

KeyScanState_0 = 0x00,
KeyScanState_1 = 0x01,
KeyScanState_2 = 0x02,
KeyScanState_Typedef;
int main(void)

vu16 KeyPortStatus = 0;
/* 定义按键扫描状态枚举变量 */
KeyScanState_Typedef KeyScanState;

while(1)

/* 查询20ms到? */
if(SysTick_GetFlagStatus(SysTick_FLAG_COUNT) == SET)

/* 读取IO电平 */
KeyPortStatus = GPIO_ReadInputData(KEYPORT) & 0x000f;
/* 进入状态机流程 */
switch(KeyScanState) ·········就是这里不明白啊啊啊 啊 啊

case KeyScanState_0:
case KeyScanState_1:
case KeyScanState_2:

你要知道哪个数据先要知道:KeyPortStatus = GPIO_ReadInputData(KEYPORT) & 0x000f;这行

我不知道你的定义我就暂时以PB口为你读取KEY的口吧,看这状态肯定是上拉然后低4位是按键,所以将口除低4位外全部清零(&0x000f)就是保留低4位二进制就是1111。
然后switch(KeyScanState) 这其实就是将第4位判断哪个具体位为0,说明哪个按下。

然后在把2进制的值用10进制表示当然你这个是已经被重新定义过的了:
KeyScanState_0,1,2.。。。这些,所以你要先看看他是定义的几才行。没有按键为0时应该是0x0f。。以此类推
参考技术A 你说的地方就是读到按键后进行按键操作啊.

if(SysTick_GetFlagStatus(SysTick_FLAG_COUNT) == SET)看是不是到了20MS.这个是去抖动的.

KeyPortStatus = GPIO_ReadInputData(KEYPORT) & 0x000f;这个是从GPIO里读按键值的,估计是看是否有按键按下吧.或者是读ADC值转换成健值.KEYPORT未见定义,不知道你的代码能否编译过.
switch(KeyScanState) 这里进行按键选择啊.在这之前应该会有KeyScanState的符值.你的代码一段一段的,要么是不全,要么是错的.

逻辑非常简单.刚学C两个月就能看懂.不打击你.追问

大哥,要是有KeyScanState的符值,你认为我还会出来问吗,我不告诉你这是大致程序了吗,全打下来写不下来,你看清了再来打击我吧

参考技术B 完整的流程:

http://www.amobbs.com/thread-5544745-1-1.html里面是你程序的出处!
int main(void)

1.初始化各个模块
while(1)

2.扫描按键;
3.给扫描到的按键赋值(包括长按键、短按键、KEY0、KEY1等)即状态;
4.根据不同的键值进行不同的业务(switch case);




很完美的状态机,我也是初学,特来膜拜的。本回答被提问者采纳

以上是关于stm32并口驱动12864,求大神看看我的程序错在哪了?编译通过但是屏幕上没显示~搞了两天了,头疼死我了、的主要内容,如果未能解决你的问题,请参考以下文章

jlxLCD12864液晶屏驱动STM32F411

如何用iar给msp430烧写程序(并口)?详细步骤

为啥keil使用JLINK调试STM32要不报错,要不就是keil挂了?求大神指点。

怎么解决用stm32 发射2m方波,求大神!!!!!

怎么在keil5里面添加stm32的库,求大神给详细步骤,谢谢

我的stm32开发板 串口和jlink都下不进去程序