OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3155|回复: 6

我用stm32驱动1602,可是什么现象都没有,大神们帮帮看看,提提意见,谢谢

[复制链接]

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2015-7-24
在线时间
19 小时
发表于 2015-7-24 18:54:39 | 显示全部楼层 |阅读模式
5金钱
#include"lcd1602.h"
#include"stm32f10x.h"
#include"stm32f10x_rcc.h"
#include"stm32f10x_gpio.h"
#include<string.h>

#define  NUMn
#define  RS_H        GPIO_SetBits(GPIOC,GPIO_Pin_2)
#define  RS_L   GPIO_ResetBits(GPIOC,GPIO_Pin_2)
#define  RW_H   GPIO_SetBits(GPIOC,GPIO_Pin_0)
#define  RW_L   GPIO_ResetBits(GPIOC,GPIO_Pin_0)
#define  EN_low      GPIO_ResetBits(GPIOF,GPIO_Pin_9)
#define  EN_high     GPIO_SetBits(GPIOF,GPIO_Pin_9)

#define  LED_H GPIO_SetBits(GPIOF,GPIO_Pin_6)
#define  LED_L GPIO_ResetBits(GPIOF,GPIO_Pin_6)





void  LCD_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能或者失能APB2外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);//使能或者失能APB2外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能或者失能APB2外设时钟

GPIO_DeInit(GPIOE);//将外设GPIOx寄存器重设为缺省值
GPIO_DeInit(GPIOF);//将外设GPIOx寄存器重设为缺省值
GPIO_DeInit(GPIOC);//将外设GPIOx寄存器重设为缺省值

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_15|GPIO_Pin_2|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速率50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化外设GPIOx寄存器

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速率50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化外设GPIOx寄存器

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速率50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化外设GPIOx寄存器
}


void  LCD_WriteBits(Write_TypeDef data_cmd,u8 value)
{  
if(data_cmd==0) RS_L ;  
 else          RS_H ;
EN_low;
RW_L; 
Delay_2us(1);
GPIO_WriteBit(GPIOE,GPIO_Pin_4,(BitAction)((value&0x80)>>7)); //D7
GPIO_WriteBit(GPIOE,GPIO_Pin_6,(BitAction)((value&0x40)>>6)); //D6
GPIO_WriteBit(GPIOC,GPIO_Pin_13,(BitAction)((value&0x20)>>5)); //D5
GPIO_WriteBit(GPIOC,GPIO_Pin_15,(BitAction)((value&0x10)>>4)); //D4
GPIO_WriteBit(GPIOF,GPIO_Pin_1,(BitAction)((value&0x08)>>3)); //D3
GPIO_WriteBit(GPIOF,GPIO_Pin_3,(BitAction)((value&0x04)>>2)); //D2
GPIO_WriteBit(GPIOF,GPIO_Pin_5,(BitAction)((value&0x02)>>1)); //D1
GPIO_WriteBit(GPIOF,GPIO_Pin_7,(BitAction)((value&0x01)));    //D0
Delay_1ms(10);
EN_high;
Delay_1ms(10);
EN_low;

}

void  LCD_Write(char*data)
{
u8 i;
for(i=0;i<strlen(data);i++)
{
   LCD_Busy();
LCD_WriteBits(DATA,data);
}  
}

void  LCD_Busy(void)
{   
      GPIO_InitTypeDef GPIO_InitStructure; 
 RS_L;      
 RW_H;
 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOE, &GPIO_InitStructure);

   while(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)==0x08)//忙信号检测关键 D7接在E4
{
  EN_low;
Delay_1ms(1);
EN_high;
Delay_1ms(1);
}
   EN_low;
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速率50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
}

void LCD_Init(void)
{
 
 Delay_1ms(15); 
 LCD_WriteBits(CMD,0X38);
 Delay_1ms(5);
 LCD_WriteBits(CMD,0X38);
 Delay_1ms(5);
 LCD_WriteBits(CMD,0X38);
  LCD_Busy();
 LCD_WriteBits(CMD,0X38);
  LCD_Busy();
 LCD_WriteBits(CMD,0x08);
    LCD_Busy();
 LCD_WriteBits(CMD,0x01);
   LCD_Busy();
 LCD_WriteBits(CMD,0x06);
LCD_Busy();
 LCD_WriteBits(CMD,0X0c);
   
}

void Delay_2us(u32 time)
{
u8 i;
while(time--)
for(i=0;i<10;i++);
}

void Delay_1ms(u32 time)
{
   u32 i;
   while(time--)
   for(i=0;i<8000;i++);
}



int main(void)
{
   
    LCD_Configuration();
LCD_Init();
    LCD_WriteBits(CMD,0X80);
LCD_Write("A");
    while(1)
   {    
  
  LCD_Write("A");
  Delay_1ms(1000);
   }  
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-25 11:50:42 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

15

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2015-5-19
在线时间
16 小时
发表于 2015-7-25 12:53:13 | 显示全部楼层
你的1602 是5V还是3.3V
回复

使用道具 举报

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2015-7-24
在线时间
19 小时
 楼主| 发表于 2015-7-26 19:18:28 | 显示全部楼层
回复【3楼】yjw123asd:
---------------------------------
5v上电,io驱动3.3
回复

使用道具 举报

19

主题

102

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2015-6-19
在线时间
1 小时
发表于 2015-7-26 21:23:49 | 显示全部楼层
论坛直接搜索程序,比较着看看。
回复

使用道具 举报

15

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2015-5-19
在线时间
16 小时
发表于 2015-7-27 08:42:48 | 显示全部楼层
回复【4楼】肥肥的猪猪:
---------------------------------
#include "stm32f10x.h"
#include "delay.h"    //必须配合delay.c和delay.h文件使用,所以要包含delay.h。
#include "display12864.h"

#define u16 unsigned short   //为了可移植性好,对这两个 STM 32 已经定义过的变量,再定义一次。
#define u8 unsigned char

/********** 以下是相关引脚定义。**************/

#define DisIO GPIOC                 //定义12864要使用的I/O端口。
#define DisClk RCC_APB2Periph_GPIOC  //定义12864要使用的I/O端口的时钟。
#define Data GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7
                                       //定义12864使用的数据引脚。
#define RS GPIO_Pin_9
#define RW GPIO_Pin_10
#define EN GPIO_Pin_11       //定义使能端使用的引脚。
#define SB GPIO_Pin_12      //定义并,串行数据模式的选择端口使用的引脚。

/*********************************************/
                     
GPIO_InitTypeDef  GPIOStru;  //定义用于定义所以引脚为输出的变量。

void IOInitOut(void)           //把所有端口初始化为推挽输出模式的函数。
{
    GPIOStru.GPIO_Mode = GPIO_Mode_Out_PP;//定义所有的引脚为推挽输出的变量初始化。
    GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
    GPIOStru.GPIO_Pin = Data|RS|RW|EN|PSB;

    RCC_APB2PeriphClockCmd(DisClk,ENABLE);
    GPIO_Init(DisIO,&GPIOStru);
}

void IOInitIn(void)           //把数据引脚初始化为浮空输入的函数。
{
    GPIOStru.GPIO_Mode = GPIO_Mode_IN_FLOATING;//定义数据引脚为浮空输入的变量初始化。
    GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
    GPIOStru.GPIO_Pin = Data;

    RCC_APB2PeriphClockCmd(DisClk,ENABLE);   //把所有端口初始化为输出模式的函数。   
    GPIO_Init(DisIO,&GPIOStru);
}

void WaitBusy(void)          //等待12864的忙状态结束的函数。
{
    IOInitIn();        //把数据引脚定义为浮空输入;
    GPIO_ResetBits(DisIO,RS);  //RS = 0.
    GPIO_SetBits(DisIO,RW);    //RW = 1.
    GPIO_SetBits(DisIO,EN);    //EN = 1.
    while(GPIO_ReadInputData(DisIO) & 0x0080); //只要位7的值,位7是忙标志位。
    GPIO_ResetBits(DisIO,EN);  //EN = 0;
    IOInitOut();      //把所有引脚定义为输出。
}

void WriteCmd(u8 cmd)    //写命令函数。
{
   WaitBusy(); 
    GPIO_ResetBits(DisIO,RS);  //RS = 0.
    GPIO_ResetBits(DisIO,RW);  //RW = 0. 
    GPIO_SetBits(DisIO,EN);    //EN = 1.
    DisIO->ODR=((DisIO->ODR & 0xff00)|cmd); //此处,只有直接操作寄存器才能
                  //达到,只改变输出数据寄存器ODR的低8位,其它位
                  //不变的目的。因为,只有低8位是数据引脚,
                  //其它位可能是控制引脚,不能改变。
    delay_ms(2);
    GPIO_ResetBits(DisIO,EN);  //EN = 0;
    delay_ms(2); 
}

void WriteData(u8 data)  //写数据函数。
{
WaitBusy(); 
    GPIO_SetBits(DisIO,RS);  //RS = 1. 
    GPIO_ResetBits(DisIO,RW);  //RW = 0. 
    GPIO_SetBits(DisIO,EN);    //EN = 1.
    DisIO->ODR=((DisIO->ODR & 0xff00)|data);  //同上。
    delay_ms(2);
    GPIO_ResetBits(DisIO,EN);  //EN = 0;
    delay_ms(2); 
}

void InitDis(void)   //初始化 12864 和要用到的 STM 32 的引脚。
{
    IOInitOut(); 
    delay_init(8);   //初始化延时函数的微妙计数基数。  
    GPIO_SetBits(DisIO,PSB);  //令PSB=1,设置为并行数据模式。
    delay_ms(2); 
    WriteCmd(0x30);  //选择基本指令集,和,8位数据模式。
    delay_ms(2);
    WriteCmd(0x0c);  //开显示,无游标,不反白.
    delay_ms(2); 
    WriteCmd(0x01);  //清除显示,并将 DDRAM 的地址计数器 AC 设为 00H.
    delay_ms(2);
    WriteCmd(0x06);  //设置,外部读写数据后,地址记数器 AC 会自动加 1。
    delay_ms(2);
    WriteCmd(0x80);  //将 DDRAM 地址计数器 AC 设为 0.
    delay_ms(2);
}

void DisStr(u8 *s)    //显示字符串的函数。
{
    while(*s != '\0')
    {
        WriteData(*s);
        s++;
        delay_ms(2);
    }
}

void DisInt(long int num)  //显示整型变量的函数,最多显示16位的整数。只能显示正数。
{
u8 temp[17];
u8 str[17];
int i=0,j=0;
while(num != 0)   //这里不能用num%10 != 0,如果num是10的整数倍,
                  //例如,100,这样就会出错,根本就不能进入循环体。
{
temp = (num%10)+0x30;
num/=10;
i++;
}
i--;           //因为i在退出循环之前还自加了一次,此时,
                //指向最后一个存储有用值的元素的后一个位置。
while(i != -1)  //因为i=0时,temp[0]还是有用值。
{
str[j] = temp;
j++;
i--;
}
str[j]='\0';  //因为i在退出循环之前还自加了一次,此时,
              //指向最后一个存储有用值的元素的后一个位置。
DisStr(str);
}

void DisFloat(float fnum) //显示有4位小数的浮点数,总位数不超过16位。
{
long int num = fnum*10000;
u8 temp[17];
u8 str[17];
int i=0,j=0;
while(num != 0)                   
{
temp = (num%10)+0x30;
num/=10;
i++;
if(i == 4)  //4位小数处理完后,加入小数点。
{
temp = '.';
i++;
}
}
i--;   
while(i != -1)
{
str[j] = temp;
j++;
i--;
}
str[j]='\0';  
DisStr(str);
}

/*以下是光标定位函数,第一个参数为行坐标,第二个为列坐标,起始坐标是1行1列。
只能以16个点的宽度为单位移动。*/

void locate16(int row, int col) 
{
switch(row)
{
case 1: WriteCmd(0x80+col-1); break;
case 2: WriteCmd(0x90+col-1); break;
case 3: WriteCmd(0x88+col-1); break;
case 4: WriteCmd(0x98+col-1); break;
}
}

/*光标定位函数定义结束。*/



#include "stm32f10x.h"

void IOInitOut(void);           //把所有端口初始化为输出模式的函数。
void IOInitIn(void);           //把数据引脚初始化为浮空输入的函数。
void WaitBusy(void);        //等待12864的忙状态结束的函数。
void WriteCmd(u8 cmd);    //写命令函数。
void WriteData(u8 data);  //写数据函数。
void InitDis(void);            //初始化 12864 和要用到的 STM 32 的引脚。
void DisStr(u8 *s);    //显示字符串的函数。
void DisInt(long int num);  //显示整型变量的函数,最多显示16位的整数。
void DisFloat(float fnum); //显示有4位小数的浮点数,总位数不超过16位。

#define  clr()  WriteCmd(0x01)  //用宏定义定义一个清除显示的函数。

/*以下是光标定位函数,第一个参数为行坐标,第二个为列坐标,起始坐标是1行1列。
只能以16个点的宽度为单位移动。*/

void locate16(int row, int col);
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-27 23:17:01 | 显示全部楼层
帮顶。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 16:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表