/*********************************************************************************************
 
 * STM32VET6开发板实验程序火牛开发板
 * 硬件: RS - RW - EN 引脚用10K电阻上拉,CRL 设置为开漏输出
 
 * 硬件: PB0--PB7 数据脚用10K电阻上拉,CRL 设置为开漏输出
 **********************************************************************************************/
 
 #ifndef      _LCD1602_H
 
 #define      _LCD1602_H
 #include "LCD1602.H"
 
 //============================端口位清除寄存器==============================================//
 
 #define  LCD1602_RS0   GPIOE->BRR= 0x00000004 //低电平PE.2
 
 #define  LCD1602_RW0   GPIOE->BRR= 0x00000010 //低电平PE.4
 
 #define  LCD1602_EN0   GPIOE->BRR= 0x00000040 //低电平PE.6
 //============================端口位设置/清除寄存器=========================================//
 
 #define  LCD1602_RS1   GPIOE->BSRR = 0x00000004 //高电平PE.2
 
 #define  LCD1602_RW1   GPIOE->BSRR = 0x00000010 //高电平PE.4
 
 #define  LCD1602_EN1   GPIOE->BSRR = 0x00000040 //高电平PE.4
#define  DATA_OUT    GPIOD->ODR//数据端口 PB0-PB7
 //==========================================================================================//
 
 //单片机系统时钟在72MHZ下的延时
 void Delay_us(unsigned long CountLing)
 
 {
 
 signed char i;
 
 while(CountLing--)
 
 {
 
 i = 10;
 
 while(i--);
 
 }
 
 }
 //==========================================================================================//
 
 //LCD1602液晶读忙状态
 void LCD_FBUF(void)
 
 {
 
 LCD1602_RS0;      //RS信号拉低
 
 LCD1602_RW1;  //RW信号拉高
 
 LCD1602_EN1;//EN信号拉高
 
 DATA_OUT = 0xFF;  //数据端口 11111111全高电平
 
 while((DATA_OUT & 0x80) == 0x80);  //判断数据端口PB7 是否一直高
 
 LCD1602_RW1;//RW信号拉高
 
 LCD1602_EN0;  //EN信号拉低
 
 }
 
 //==========================================================================================//
 
 //LCD1602写指令子函数
 void Write_LCD1602_Instruction_Com(unsigned char Com)
 
 {
 
 LCD_FBUF();             //读忙状态
 
 LCD1602_RS0;      //RS信号拉低写指令
 
 LCD1602_RW0;      //RW信号拉低
 
 LCD1602_EN0;      //EN信号拉低
 
 DATA_OUT = Com;      //数据端口指令输入
 
 Delay_us(340);      //延时1ms
 
 LCD1602_EN1;       //EN信号一个高脉冲
 
 Delay_us(340);      //延时1ms
 
 LCD1602_EN0;
 
 }
 //==========================================================================================//
 
 //LCD1602写数据子函数
 
 
 
 void Write_LCD1602_Instruction_Data(unsigned char Date)
 
 {
 
 LCD_FBUF();             //读忙状态
 
 LCD1602_RS1;      //RS信号拉高写数据指令
 
 LCD1602_RW0;
 
 LCD1602_EN0;      //EN信号拉低
 
 DATA_OUT = Date;        //数据端口数据输入
 
 Delay_us(340);      //延时1ms
 
 LCD1602_EN1;        //EN信号一个高脉冲
 
 Delay_us(340);      //延时1ms
 
 LCD1602_EN0;
 
 }
 //==========================================================================================//
 
 //LCD1602写指令和写数据子函数
 
 
 
 void Write_LCD1602_Instruction_Com_Data(unsigned char CountLiey, unsigned char Date)
 
 {
 
 if(CountLiey == 0)          //CountLiey == 0 写指令
 
 {
 
 Write_LCD1602_Instruction_Com(Date);    // 写指令
 
 }
 
 else           //CountLiey !=0 写数据 
 
 {
 
 Write_LCD1602_Instruction_Data(Date);  //不等于0写数据
 
 }
 
 }
 //==========================================================================================//
 
 //LCD1602写指令初始化子函数
 void Init_LCD1602(void)
 
 {
 
 Write_LCD1602_Instruction_Com(0x38);   //设置16×2显示,5×7点阵,8位数据接口
 
 Delay_us(6);   //延时 200us
 
 Write_LCD1602_Instruction_Com(0x38);   //设置16×2显示,5×7点阵,8位数据接口
 
 Delay_us(6);   //延时 200us
 
 Write_LCD1602_Instruction_Com(0x0C);     //设置打开显示
 
 Delay_us(6);   //延时 200us
 
 Write_LCD1602_Instruction_Com(0x06);     //读或写一个字符后地址指针加1
 
 Delay_us(6);
 
 Write_LCD1602_Instruction_Com(0x01);   //显示清屏
 
 Delay_us(6);
 
 }
 #endif
 //========================================END==================================================//
 
 
 
 /********************************************************************************************
 
 *   STM32VET6开发板实验程序火牛开发板
 
 *********************************************************************************************/
 
 #include "stm32f10x_lib.h"
 
 #include "LCD1602.H"
 
 //#include "DS18B20.H"
 typedef volatile unsigned charuint8;
 
 typedef volatile unsigned int uint16;
 
 typedef volatile unsigned longuint32;
 //==========================================================================================//
 
 //配置GPIO端口
 void GPIO_InitStructReadtempCmd(void)
 
 {
 
 GPIO_InitTypeDef GPIO_InitStruct; 
 
 /*GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;//DS18B20数据脚
 
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
 
 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//输出速率50MHZ
 
 GPIO_Init(GPIOC, &GPIO_InitStruct); *///GPIOC端口初始化
 
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 |GPIO_Pin_4 | GPIO_Pin_6;// LCD1602 RS-RW-EN脚
 
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
 
 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速率50MHZ
 
 GPIO_Init(GPIOE, &GPIO_InitStruct); //GPIOE端口初始
 
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |//数据脚 PB0-PB7
 
 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
 
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
 
 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速率50MHZ
 
 GPIO_Init(GPIOD, &GPIO_InitStruct); //GPIOD端口初始化
 
 }
 //==========================================================================================//
 
 //配置GPIO外设时钟
 void RCC_APB2PeriphReadtempyCmd(void)
 
 {
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); // 开启GPIOD外设时钟
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 开启GPIOE外设时钟
 
 }
 //==========================================================================================//
 
 //函数主题
 int main(void)
 
 {
 
 RCC_APB2PeriphReadtempyCmd();//外设时钟初始化 //注意外设初始化一定要在GPIO端口配置初始化前面
 
 GPIO_InitStructReadtempCmd();  //GPIO端口配置初始化
 while(1)
 
 {
 
 Write_LCD1602_Instruction_Com_Data(0, 0x80+4); //0是写指令
 
 Write_LCD1602_Instruction_Com_Data(1, 'A' ); //1是写数据
 
 }
 
 }