1

关于投票
DS18B20的AVR驱动

AVR接DS18B20,我在OURAVR上发过

  //m26温度测量通过串口传到电脑;8MHZ
#define CL_DQ PORTD&=~(1<<PD7)
#define SET_DQ PORTD|=(1<<PD7)
#define SET_OUT DDRD|=(1<<PD7)
#define SET_IN  DDRD&=~(1<<PD7)
#define IN_DQ  PIND&(1<<PD7)

 

void write_1820(uchar x)
{  uchar m;  
    CLI();
    for(m=0;m<8;m++)
    {
      CL_DQ;
       if(x&(1<<m))    //写数据,从低位开始
       {Delay_nus(2);SET_DQ; }
       else
      CL_DQ;
       Delay_nus(60);   //15~60us
      SET_DQ;
    Delay_nus(10);
    }
    SET_DQ;
 SEI();
}
uchar read_1820()
{   uchar temp,k,n; 
    CLI();
  temp="0";
    for(n=0;n<8;n++)
       {
      CL_DQ;
     //Delay_nus(2);      
      SET_DQ;
      //delay(3);    
      SET_IN;
   Delay_nus(1);
      k="IN"_DQ;    //读数据,从低位开始
      if(k)
      temp|=(1<<n);
      else
      temp&=~(1<<n);
      Delay_nus(70); //60~120us    
      SET_OUT;
   }
   SEI();
   return (temp);
}


void init_1820(void)
 {CLI();
 SET_OUT;
  SET_DQ;//输出1
  CL_DQ;
  Delay_nus(550);//拉低一段时间
  SET_DQ;//释放
  SET_IN;//输入
  Delay_nus(60);
  while(IN_DQ)  {;}//等待回复
  Delay_nus(240);//回复的低电平在60到240US
  SET_OUT;
  SET_DQ;//回到初始DQ=1;
  SEI();
 }

void Temper(void) //主函数
{
 
      uint j,tem;
  uchar i,temh,teml;
     init_1820();  //复位18b20
   write_1820(0xcc);   // 发出转换命令 搜索器件
      write_1820(0x44);     //启动
      for(j=1000;j>1;j--)
         Delay_nus(1000);//转换一次12位的 最多750MS
       init_1820();
      write_1820(0xcc);  //发出读命令
      write_1820(0xbe);
 
      teml="read"_1820();  //读数据
      temh="read"_1820();
   tem=(teml>>4)+(temh<<4);
   Int_to_Char(tem,Date);
      puts(Date);
  if(LCD)
  {
 
  LCD_write_string(2,1,"is :");
  LCD_write_string(8,1,Date);
  LCD_write_string(13,1,"du");
  }

 
     //每次转换需要延时
   Delay_nms(100);
}

系统分类: 嵌入式
用户分类: AVR
标签: 无标签
来源: 原创
发表评论 阅读全文(196) | 回复(0)

1

关于投票
1602的AVR的C驱动(4线方式)

 

参考了OURAVR的程序,自己写了一个,加上光标和屏幕滚动代码
#define LCD_EN_PORT    PORTA   //以下2个要设为同一个口
#define LCD_EN_DDR     DDRA
#define LCD_RS_PORT    PORTA   //以下2个要设为同一个口
#define LCD_RS_DDR     DDRA
#define LCD_DATA_PORT  PORTA   //以下3个要设为同一个口
#define LCD_DATA_DDR   DDRA    //一定要用高4位
#define LCD_DATA_PIN   PINA
#define LCD_RS         (1<<PA1) //0x02  portA1       out
#define LCD_EN         (1<<PA3) //0x08   portA3       out
#define LCD_DATA       ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7)) //0xf0   portA4/5/6/7 out
uchar  LCD="1"  ; //是否让LCD显示   0,不显示;;;1显示
/*--------------------------------------------------------------------------------------------------
函数说明
--------------------------------------------------------------------------------------------------*/
void LCD_init(void);
void LCD_en_write(void);
void LCD_write_command(unsigned  char command) ;
void LCD_write_data(unsigned char data);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data);

void LCD_Init(void)         //液晶初始化
{
 LCD_DATA_DDR|=LCD_DATA;   //数据口方向为输出
  LCD_EN_DDR|=LCD_EN;       //设置EN方向为输出
  LCD_RS_DDR|=LCD_RS;       //设置RS方向为输出

  CLI();
 PORTA&=~0x04;//RW=0
 DDRA=0xff;
 LCD_write_command(0x30);
 Delay_nms(10);
 LCD_write_command(0x30);
 Delay_nms(5);
 LCD_write_command(0x30);
 Delay_nms(5);
  LCD_write_command(0x28);//写指令,4位数据线,5*10字体
  LCD_en_write();
  Delay_nms(4);
  LCD_write_command(0x28);  //4位显示
  LCD_en_write();
  LCD_write_command(0x0c);  //显示开 光标关,字符不闪烁
  LCD_en_write();
  SEI();
  Delay_nms(2);
}

void LCD_en_write(void)  //液晶使能
{
  LCD_EN_PORT|=LCD_EN;    //
 Delay_nus(1);
  LCD_EN_PORT&=~LCD_EN;  //  给出下降沿
}

void LCD_write_command(unsigned char command) //写指令   E下降,RS=0,RW=0
{
 Delay_nms(6);
  LCD_RS_PORT&=~LCD_RS;        //RS=0
  LCD_DATA_PORT&=0X0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写高四位
  LCD_en_write();               //E下降
  command="command"<<4;          //低四位移到高四位
  LCD_DATA_PORT&=0x0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写这次低四位到数据线高4位
  LCD_en_write();
 
}

void LCD_write_data(unsigned char data) //写数据     E下降,RS=1,RW=0
{
  Delay_nms(6);
  LCD_RS_PORT|=LCD_RS;       //RS=1
  LCD_DATA_PORT&=0X0f;       //清高四位
  LCD_DATA_PORT|=data&0xf0;  //写高四位
  LCD_en_write();
  data="data"<<4;               //低四位移到高四位
  LCD_DATA_PORT&=0X0f;        //清高四位
  LCD_DATA_PORT|=data&0xf0;   //写低四位
  LCD_en_write();
}


void LCD_set_xy( unsigned char x, unsigned char y )  //写地址函数
{
    unsigned char address;
    if (y == 0) address = 0x80 + x;  // 最高位是1,另七位才是地址 故有+0x80
    else   address = 0xc0 + x;
    LCD_write_command( address);
}
 
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
{
    LCD_set_xy( X, Y ); //写地址   
    while (*s)  // 写显示字符
    {
      LCD_write_data( *s );
      s ++;
    }
     
}

void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
{
  LCD_set_xy( X, Y ); //写地址
  LCD_write_data( data);
 
}
/*光标移动*/
void CursorScroll(void)
{
 
 
 LCD_write_command(0x10); //光标左移
  
}
/*画面滚动*/
void ScreenScroll(void)
{
 //while(1)
 {
 LCD_write_command(0x18);  //画面左滚
 Delay_nms(300);
 } 
}

 

 

 

 


 

系统分类: 单片机
用户分类: AVR
标签: LCD1602驱动
来源: 无分类
发表评论 阅读全文(257) | 回复(0)

1

关于投票
MEGA8做的多功能低功耗电子子表

点击开大图

    

       全功能迷你电子表

                        作者:chuanhuibh  版本 V1.0

  本电子表是基于MEGA8单片机和LED数码管为主体设计的,它功能全面,可以显示月,日,时,分,秒,还可以设定闹钟,设计时考虑到省电,还可以进入休眠状态(不显示,但时钟仍运行),以下是该表的使用说明。

12位分3页设置依次是:

 2位:分2;

        UP

LEFT_ SET_ RIGHT

      DOWN

 2位:日2;

 闹钟的时2位:分2

设置完后再按SET键即可回到正常的显示模式(时:分),若要当秒表,则按RIGHT,可实现两种显示切换。

正常显示时,按DOWN键,可以显示日期(月:日),过几秒后回到正常显示模式。LEFT休眠,重按后苏醒。

    本电子表使用35号电池供电一共5个键,和一个位于电路板和电池盒间的电源开关。5个键按空间位置分别是LEFTRIGHTUPDOWN,以及中间的SET,位置和名字对应。

键位设置

 上电后,按RIGHT键可以实现(时:分)显示到(分:秒)显示模式的切换。按SET键可以进入设置模式,一共有12位要设置,分为3页(因为是4个数码管),此时数码管显示第一位,按RIGHT依次像右移动,按UP键所显示的位会加1,加到90

/* 作者 chuanhuibh
   全功能电子表,
   LED, 月,日,时,分,秒,闹钟
   可以选择休眠,时钟运行,CPU 和大部分外设停止,
   外部32768 HZ每秒中断唤醒
   5键设置 ,用法见帖子说明
   MEGA8  ICCAVR
*/
/*
 PORTD LED的数据
 PORTB0~3 选通
 PC1~5  按键   见key.h
*/
#include"iom8v.h"
#include"macros.h"
#include"key.h"

const char Table[10]={0x3f,0x06,0x5b,0x4f,0x66,
                0x6d,0x7d,0x07,0x7f,0x6f};
const char MONTH[12]={31,28,31,30,31,30,31,31,
                      30,31,30,31};
char Date[12]={1,1,1,1,2,2,2,2,3,3,3,3};
char sleep="0",wei=0,wei_1=0,second,minute,hour,
     minute_s,hour_s,
  month="10",data=22,page=0;


void Delay_nus(unsigned i)
{
   for(;i>1;i--){;}
}
void Delay_1ms()
{unsigned i;
   for(i=125;i>1;i--)
   {Delay_nus(1);
     }
}
void Delay_nms(unsigned i)
{
   for(;i>1;i--)
   {Delay_1ms();}
}
void Display(char *p)

{char i,sel=0x01;
 if(sleep) return;
  for(i=0;i<4;i++)
     {
   PORTB=~sel;     // 0 表示选通
   PORTD="Table"[p[i]];
   Delay_nms(2);
   PORTD="0x00";
   sel="sel"<<1;
  }
}
void Sound(char i)
{
   char n;
   for(n=0;n<i;n++)
      {
    PORTC&=~(1<<PC0);
    PORTC|=(1<<PC0);
    Delay_nms(15);
    PORTC&=~(1<<PC0);
    Delay_nms(15);
    }
}

void Ring(void)
{
 
 char temp="5";PORTD=0x00;
 while(temp>0)
 {
  Sound(1);
  Delay_nms(200);
  Sound(1);
  Delay_nms(200);
  Sound(1);
  Delay_nms(200);
  Sound(1);
  Delay_nms(400);
  Sound(1);
 
  temp--;
 }
}
 void Io_Init(Void)
{DDRD=0xFF;
 PORTD=0xff;
 DDRC=0x01;PORTC=0xfe;

 DDRB=0x0F;
 PORTB=0xff;
 
}
void Init_timer2(void)
{
 TCCR2=0x00;    //先关再操作
 ASSR=(1<<AS2);     //异步时钟,32768HZ
 TCNT2=0xe0;
 TCCR2=0x07;     //1024 fen
 SREG=SREG|0x80;
 TIMSK|=(1<<TOIE2);
}
void BIN_to_CLK(char *p)
 {
 if(page)
 { p[3]=second%10;
  p[2]=second/10;
  p[1]=minute%10;
  p[0]=minute/10;
  }
  else{
 
  p[3]=minute%10;
  p[2]=minute/10;
  p[1]=hour%10;
  p[0]=hour/10;
  }
 }
 void DATA_to_CLK(char *p)
 {
  p[7]=data%10;
  p[6]=data/10;
  p[5]=month%10;
  p[4]=month/10;
 }
 
char Key_Value(void)
{
 char temp,value;
 
 temp=PINC&0x3e;
 //
 Delay_nms(8);
 if(temp==(PINC&0x3e))//延时后键值未变,消抖成功
 
    switch(temp)
     {
     case 0x3c:  value="SET"; break;
     case 0x3a:  value="DEC"; break;
     case 0x36:  value="ADD"; break;
     case 0x2e:  value="LEFT"; break;
     case 0x1e:  value="RIGHT"; break;
     default:    value="ERROR";
     }
 while(temp==(PINC&0x3e));//直到键松开
 Delay_nms(25);
 return value;
}
void Display_wei(char i)
{PORTD=Table[Date[wei_1]];PORTB=~(1<<wei);
}
void Key_Process()
{char temp, n;
 
 temp=Key_Value();
 if(temp==DEC) 
    {for(n=0;n<150;n++)
   {
     DATA_to_CLK(Date);
     Display(Date+4);
    }
   return;
  }
 else if(temp==LEFT)
       {
     if(sleep==0) {
                 sleep="1";
     
        MCUCR="0x90";
                       asm("SLEEP");
        }
   else sleep="0";
   
  return;
  }      
     
else if(temp==RIGHT) 
   {if (page==0) page="1";
    else page="0";
   }
if(temp!=SET)
    return;
 wei_1=0;Display_wei(wei_1);
 while(1)
     {
   temp="Key"_Value();
   switch(temp)
     {
   case SET: hour="Date"[1]+Date[0]*10;
             minute="Date"[3]+Date[2]*10;
       month="Date"[5]+Date[4]*10;
       data="Date"[7]+Date[6]*10;
       hour_s=Date[8]*10+Date[9];
       minute_s=Date[10]*10+Date[11];
       return;
  
   case RIGHT: if(wei_1<11) wei_1++;
               else wei_1=0;
      wei="wei"_1%4;
              break;
   case ADD:  if(Date[wei_1]<9) Date[wei_1]++;
               else Date[wei_1]=0;
              break;
   default:   break;
  }
   Display_wei(wei_1);
  
  }
 
 /**/
}
void main(void)
{
  Io_Init();
  Init_timer2();
  TIMSK =1<<TOIE2;
  SEI();
 // Sound(1);
 
while(1)
    {
  BIN_to_CLK(Date);
  Display(Date) ;
 if((PINC&0x3e)!=0x3e)  Key_Process();
 
 if(sleep)   {MCUCR=0x90;asm("SLEEP");}
 }
}
#pragma  interrupt_handler Timer2:5
void Timer2(void)
{TCNT2=0xe0;
 second++;
 //sleep=0; 
 MCUCR=0x00;
//Sound(1);
if(second==60)
     {minute++;second=0;
  if(minute==minute_s&&hour==hour_s&&hour!=0&&minute!=0)
   Ring();}
if(minute==60)
      {hour++;minute=0;
  
   }
if(hour==24)
       {hour=0;data++;}
if(data==MONTH[month])
       {data=1;month++;}

 
 
}

 

key.h
#define SET 0x01
#define LEFT 0x02
#define RIGHT 0x03
#define ADD  0x04
#define DEC  0x05
#define ERROR  0x06

系统分类: 单片机
用户分类: AVR
标签: MEGA8电子表
来源: 无分类
发表评论 阅读全文(130) | 回复(0)

2

关于投票
基于AVR的测量与机械控制一体化平台(详细资料)

这个论文是我参加学校竞赛时写的,做的是一个兼顾测量和机电控制的平台,有PC上的软件控制,当然也可有4X4矩阵键盘控制,还有16X2字符液晶。
可以控制多路 舵机,直流电机,2相步进电机。可以测量电压,温度,转速,频率等等。 另外还可以作信号发生器(不是单片机,是ICL8038),逻辑分析仪。
   毕竟是第一次做复杂的东西,实间很紧,学院给钱有限,东西都很粗,电路图有些都没画,论文和软硬件多次更改,连我自己都搞不清哪个版本错误少。
   参加比赛的方案受到OURAVR 的很多启发,也参考了一些例程,一并表示感谢。我是第一作者(当然还有几位拍档),完成所有上下软件设计,还有大部分硬件。现在把这个传上来,作为这个论文是我参加学校竞赛时写的,做的是一个兼顾测量和机电控制的平台,有PC上的软件控制,当然也可有4X4矩阵键盘控制,还有16X2字符液晶。

这个是PDF文档,代码在PDF文档后半部分点击下载

系统分类: 单片机
用户分类: AVR
标签: 很详细的一个工程(包含接口很广有测量和机电控制)