找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1221|回复: 0
收起左侧

单片机简单程序试试发

[复制链接]
ID:276209 发表于 2018-1-15 15:24 | 显示全部楼层 |阅读模式
#include <avr/io.h>
#include <util/delay.h>

//口定义
#define PORT_DHT PORTC
//口方向定义
#define DDR_DHT DDRC
//读取口定义
#define PIN_DHT PINC
//数据位定义
#define BIT_DHT PC4


#define RS PA0 //数据/命令控制端 0命令,1 数据


#define RW PA1 //读/写选择控制端 0写,1读



#define E PA2 //使能端 下降沿读,高电平写


#define                L_DHT                PORT_DHT&=~(1<<BIT_DHT)                        //数据线强制拉低


#define                H_DHT                PORT_DHT|=(1<<BIT_DHT)                                //数据线强制拉高


#define                O_DHT                DDR_DHT|=(1<<BIT_DHT)                                //Mega16控制总线,PD4为输出


#define                P_DHT                DDR_DHT&=~(1<<BIT_DHT)                            //释放总线,PD4为输入


#define                I_DHT                PIN_DHT&(1<<BIT_DHT)                                //数据线的状态


void LCDPort_Init(void); //液晶端口初始化
void LCD_Init(void); //LCD 初始化
void Write_Com(unsigned char LCD_Com); //LCD 写指令
void Write_Data_Byte(unsigned char LCD_Data); //LCD 写字节数据
void Write_Place_xy(unsigned char x,unsigned char y); //指定当前写字符的位置
void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data);//在指定的(x,y)位置上写入字符串数据
void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data);//在指定的(x,y)位置上写入字符数据
void Check_Busy(void); //读写检测函数,每次对液晶操读作前都要进行写检测
void Delayus(unsigned int lus); //us延时函数
void Delayms(unsigned int lms); //ms延时函数
/*******************************************************/
unsigned  Reset()
{
        O_DHT;
        H_DHT;
        _delay_us(2);
        L_DHT;
        _delay_us(19);
        P_DHT;
        _delay_us(20);
        if(I_DHT)
        return 0;
        else
        return 1;
}
int main(void)
{       
        _delay_ms(1000);
        unsigned char tdata[5];
        unsigned long u16Flag; // 超时计数
        unsigned char iiii;
        unsigned long u32I; // 接收数据临时变量
        unsigned long ReceiveValue = 0; // 接收数据包变量
        unsigned long ReceiveValue1 = 0; // 接收校验和变量
        unsigned int ReceiveHighByte; // 分解数据包 湿度
        unsigned int ReceiveLowByte; // 分解数据包温度
        LCDPort_Init();
        LCD_Init();
        Write_Data_String(0,0,"ddddddd");
        while(1)
        if(Reset())
        {        P_DHT;
                while((!(I_DHT)) && ((u16Flag++)<50000));
                ReceiveValue = 0;
                ReceiveValue1 = 0;
                u16Flag = 0;
                while((I_DHT) && ((u16Flag++)<50000));
                for(u32I=0x80000000; u32I>0; u32I>>=1)
                {
                        u16Flag = 0;
                        while((!(I_DHT))&& ((u16Flag++)<3000));
                        u16Flag = 0;
                        _delay_us(28);
                        if(I_DHT)
                        {
                                ReceiveValue |= u32I;
                        }
                        while((I_DHT)&&((u16Flag++)<300));
                }
                for(u32I=0x80;u32I>0;u32I>>=1)
                {
                        u16Flag = 0;
                        while((!(I_DHT))&&((u16Flag++)<3000));
                        u16Flag = 0;
                        _delay_us(28);
                        if(I_DHT)
                        {
                                ReceiveValue1 |= u32I;
                        }
                        while((I_DHT)&&((u16Flag++)<300));
                }
                while(!(I_DHT));
                O_DHT;
                H_DHT;
                ReceiveLowByte =(unsigned int )( ReceiveValue&0x0000FFFF);
                ReceiveHighByte = ReceiveValue>>16;
                /****************************display******************************/
                        tdata[0]=*((unsigned char*)(&ReceiveHighByte) + 1)/10;
                      tdata[1]=*((unsigned char*)(&ReceiveHighByte) + 1)%10;
                      tdata[2]=*((unsigned char*)(&ReceiveLowByte) + 1)/10;
                        tdata[3]=*((unsigned char*)(&ReceiveLowByte) + 1)%10;
                        Write_Com(0xc0);
            Write_Data_Byte( tdata[0]+0x30 );//显示湿度十位
                        Write_Com(0xc1);
                        Write_Data_Byte( tdata[1]+0x30 );//显示湿度个位
                        Write_Com(0xc2);
                //        Write_Data_Byte("%");
                        Write_Com(0xc4);
                        Write_Data_Byte( tdata[2]+0x30 );//显示温度十位
                        Write_Com(0xc5);
                        Write_Data_Byte( tdata[3]+0x30 );//显示温度个位
                        Write_Com(0xc6);
                          Write_Data_Byte(0xdf);//显示"。"
                          Write_Com(0xc7);
                          Write_Data_Byte('C');

        }
        else
        {
               
        }

}








































































void LCDPort_Init()
{
  //LCD 数据端口设置
  PORTD = 0X00; //
  DDRD = 0XFF; //配置端口PD全部为输出口,LCD 数据端口
  //LCD 控制端口设置
  PORTA &= ~((1 << RS) | (1 << RW) | (1 << E)); //
  DDRA |= (1 << RS) | (1 << RW) | (1 << E);
}


//LCD 初始化
void LCD_Init()
{
Write_Com(0X01); //清屏
Delayms(5);
Write_Com(0X38); //显示模式设置 16x2显示,5x7点阵,8 位数据接口
Delayms(5);
//Write_Com(0X0f); //显示开关控制,开显示,光标显示,光标闪烁
Write_Com(0X0c); //显示开关控制,开显示,光标不显示,光标不闪烁
Delayms(5);
Write_Com(0X06); //光标设置,读或写一个字符后,地址指针加一,光标加一,整屏不移动
Delayms(5);
}


//LCD 写指令
void Write_Com(unsigned char LCD_Com)
{
Check_Busy();
PORTA &= ~(1 << RS); //RS=0,写命令
PORTA &= ~(1 << RW); //RW=0,写指令
PORTA |= (1 << E); //E=1,写操作
Delayms(1);
PORTD = LCD_Com; //指令送数据端口
PORTA &= ~(1 << E); //E=0,停止写操作
Delayms(1);
}


//LCD 写字节数据
void Write_Data_Byte(unsigned char LCD_Data)
{
  Check_Busy();
  PORTA |= (1 << RS); //RS=1,写数据
  PORTA &= ~(1 << RW); //RW=0,写指令
  PORTA |= (1 << E); //E=1,写操作
  Delayms(1);
  PORTD = LCD_Data; // 数据送数据端口
  PORTA &= ~(1 << E); //E=0,停止写操作
  Delayms(1);
}


//指定当前写字符的位置
void Write_Place_xy(unsigned char x,unsigned char y)
{
  unsigned char address;
  if(y == 0) //行位置
   {
    address = 0x80 + x; //列位置,
    }
  else
   {
    address = 0x80 + 0x40 + x; //
     }
  Write_Com(address); //写地址
}


//在指定的(x,y)位置上写入字符串数据
void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data)
{
  Write_Place_xy(x,y); //写地址
  while(*data)
  {
   Write_Data_Byte(*data); //写字符串
   data++; //指针地址加1
   }
}


//在指定的(x,y)位置上写入字符数据 x列位置,y行位置
void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data)
{
  Write_Place_xy(x,y); //
  Write_Data_Byte(data); //
}


//读写检测函数,每次对液晶操作前都要进行读写检测
void Check_Busy()
{
  DDRD = 0X00; //PB口置为输入口,准备读取数据
  PORTA &= ~(1 << RS); //RS=0,读命令
  PORTA |= (1 << RW); //RW=1,读指令
  PORTA |= (1 << E); //E=1,使能
  while(0X80 & PIND); //监测忙信号,直到忙信号为0,才能进行读写操作
  PORTA &= ~(1 << E); //E=0
  DDRD = 0XFF; //PB口置为输出口,准备向端口发送数据
}


//us级别的延时函数
void Delayus(unsigned int lus)
{
while(lus--)
  {
   _delay_loop_2(4); //_delay_loop_2(1)是延时4 个时钟周期,参数为4 则延时16
    //个时钟周期,本实验用16M晶体,则16 个时钟周期为16/16=1us
  }
}


//ms级别的延时函数
void Delayms(unsigned int lms)
{
  while(lms--)
  {
   Delayus(1000); //延时1ms
   }
}
















接线图.JPG
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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