这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » yeximei MCU DIY进程帖

共17条 2/2 1 2 跳转至
助工
2011-12-06 19:18:57     打赏
11楼

测试程序4:双色点阵封装的单色8*8点阵。红色接口是P0,PA0。显示开始时全暗(接口原因,有点微亮),然后每隔1秒点亮一行。如果换成P0,P2接口的单色点阵,没有微亮,但P2口LCD显示要用。因此没有给出这种方式的程序。总之,点阵连接方式不好,只做一个基本测试。
char code ledmcode[]= {0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80 };
void ledm(void)
{ char i;
 DISPWM(0);//关数码管或数码管显示固定
 for(i=8;i>0;i--)
 { LEDMR=ledmcode[i];DISPCLK=0;DISPCLK=0;DISPCLK=1;DISPCLK=1;DISPCLK=0;
  LEDMR=ledbuf[i-1];LEDMG=ledbuf[i+8-1];
  delayNms(1);
  LEDMR=0;DISPCLK=0;DISPCLK=1;DISPCLK=0;

 }
}
在定时中断中,写入要显示的内容ledbuf。
ledbuf[second%8]=0;

视频地址:http://player.youku.com/player.php/sid/XMzI5NzMzMDM2/v.swf


助工
2011-12-12 19:46:24     打赏
12楼

测试程序5:按键扫描与处理程序。接成4*4,其中P3。7与数码管写脉冲共用。因些第1列按键时会影响显示。不知大家的是否也有这样情况。按键扫描程序用输出反转法设计。先输出高4位0,测出(行或列),然后以这个行或列为输出,得到列或行。扫描速度较快。然后用移寄存器方式实现一次按键只产生一个动作。
unsigned char code KEYCODE[]={0x77,0x7b,0xbb,0xdb,0x7d,0xbd,0xdd,0x7e, //0-7
                              0xbe,0xde,0xb7,0xeb,0xed,0xee,0xd7,0xe7 }; //8,9,.,left,right,down,up,ok
 /*
 7   8   9      ok
 4   5   6      up
 1   2   3      down
 0   .   left   right
 */
char keyscan()
{
//输入程序代码
 char i;
 KEYIO=0x0f;
 delayN10us(1);
 keytemp=KEYIO;keytemp|=0xf0;
 KEYIO=keytemp;
 delayN10us(1);
 keytemp=KEYIO;//键值
 for(i=0;i<16;i++)
 {
  if(keytemp==KEYCODE[i]) break;
 }
 keytemp=i;
 if(keytemp!=16 & keybuf==16) {keybuf=keytemp; return keybuf;}
 else
 {keybuf=keytemp;
 return 16;}//无按键
}
键值处理部分:
先判断有没有按键,然后再执行键值显示或对指定单元加1。keypress=16为无按键。
void keyp(char key)
{
 if(key!=16)
  if(key=0xe)
   {dispbuf[4]++;dispbuf[4]&=0xf;}
  else
   dispbuf[4]=key;
 keypress=16;   

}

视频地址:http://player.youku.com/player.php/sid/XMzMxNzY3MjY0/v.swf


菜鸟
2011-12-12 21:47:44     打赏
13楼

很不错哦


助工
2011-12-13 09:38:51     打赏
14楼
感谢,欢迎指正。

助工
2011-12-13 10:00:02     打赏
15楼
测试程序6:LCD1602测试程序。设计了字符显示,光标控制,显示移动,自定义字符设计等程序,LCD底层驱动部分有读,写,模式设置(数据或命令、状态),复位。
char read1602(void)
{char dat;
 LCDD=255;
 LCDRW=1;
 LCDE=1;
 dat=LCDD;
 LCDE=0;
 return dat;
}
/*
data:写入的数据
return:返回值1:有错,0:无错
*/
char write1602(char dat)
{
 char i;
 LCDD=255;
 LCDRW=1;
 LCDE=1;
 for(i=0;i<200;i++)
 { if(!(LCDD&0x80)) break;
      if(i>180)//
   return 1;
 }
 LCDRW=0;
 LCDD=dat;
 LCDE=1; LCDE=0; 
 return 0;
}
/*
m=0:命令或状态  m=1:数据
*/
void mode1602(char m)
{
 if (m)  LCDRS=1;
 else LCDRS=0;
 LCDE=0;
}
下面仅给出显示字符串的函数。
/*
* context:输入的字符指针
  输入后自动后移一位
*/
void lcdprint(char * context)
{char temp;
 char *i;
 i=context;
 mode1602(1);//0:命令或状态  1:数据
 while((*i)!=0 )
 { temp=write1602(* i);
  i++;
 }
}
存在的问题:有时候显示字符时中间少显示几个字符。例如,第一行显示1234567890,只显示1234  6789。5的位空出,但不显示。


1602做自定义字库时,用5*7点阵。我用8*8的设计(前3列没用,最后一行没用),字要靠右边写。效果如时钟程序所示。

助工
2011-12-14 11:00:03     打赏
16楼
测试程序7:DS1302时钟芯片。刚开始时间能设置,能读写。后来在单步执行的过程中,一缕烟从DS1302上冒出来。不知是什么原因。芯片很烫。
现在好了。(在DS1302的数据端串入一个电阻可能更好,欢迎指正)。
时间设置与时间读取都用批传送模式。自定义了几个汉字。先上个图。



void ds1302wrNb(unsigned char * string)
{
//输入程序代码
 DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;
 DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;
 DS1302CLK=0;
 temp=0xbe;//read:80   write:81
 for(i=0;i<8;i++)                //write command to DS1302
 {
  if(temp&1) DS1302IO=1;else DS1302IO=0;
  temp=temp>>1;
  DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;
  DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;
 }
 while(*string!=0)
 {
 temp=*string;string++;
 for(i=0;i<8;i++)                //write data to DS1302
  {
  if(temp&1) DS1302IO=1;else DS1302IO=0;
  temp=temp>>1;
  DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;
  DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;
  }
 }
 temp=0;//写  保护位
 for(i=0;i<8;i++)                //write data to DS1302
 {
  if(temp&1) DS1302IO=1;else DS1302IO=0;
  temp=temp>>1;
  DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;
  DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;
 }
 DS1302RST=0;
}

void d1302rdN(void)
{
//输入程序代码
 
 DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;DS1302RST=0;
 DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;DS1302RST=1;
 DS1302CLK=0;
 temp=0xbf;//read:80   write:81
 for(i=0;i<8;i++)                //write command to DS1302
 {
  if(temp&1) DS1302IO=1;else DS1302IO=0;
  temp=temp>>1;
  DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;
  DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;
 }
 DS1302IO=1;
 for(j=0;j<7;j++)
 { temp=0;
  for(i=0;i<8;i++)
  { temp>>=1;
   if (DS1302IO) temp+=128;
   DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;DS1302CLK=1;
   DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;DS1302CLK=0;
  }
  dispbuf[j]=temp;
 }
DS1302RST=0;
}

/*
func:0: time stop
  1: time start
  2: write protect
  3: write free
  4: charge mode 1
  5: charge mode 2
*/
void ds1302ctr(unsigned char func)
{
//输入程序代码
 if (func==0) {temp=ds1302read(0); temp|=0x80;ds1302write(0,temp); } //time stop
 if (func==1) {temp=ds1302read(0); temp&=0x7f;ds1302write(0,temp); }  //time start
 if (func==2) {ds1302write(7,0x80);   }
 if (func==3) {ds1302write(7,0x0);   }
}

助工
2011-12-15 14:52:13     打赏
17楼

测试程序8:DS18B20温度传感器。主要包含基本驱动(读写,复位)和启动转换,读温度,温度转换成ASCII码程序。注意的是:1、各部分延时应准确。2、每次发命令的时候应先发0CCH跳过命令(也可以发匹配命令55H)。


void DS18B20Start(void)
{
//输入程序代码
 temp=DS18B20RST();
 if(!temp)
 {
  DS18B20write(0xcc);
  DS18B20write(0x44);
 }
}
int DS18B20dat(void)
{int dat;
 temp=DS18B20RST();
 if(!temp)
 { DS18B20write(0xcc);//不发出跳过命令,就要发ID码
  DS18B20write(0xbe);
  temp=DS18B20read();//low 8
  dat=DS18B20read();//high 8
  dat<<=8;
  dat+=temp;
 }

 return dat;
}
基本驱动程序。
void delayNus(unsigned char N)//1:20us   每个数8uS
{ unsigned char s;
 for (s=0; s<N;s++);
}


//1:没有检测到DS18B20, 0:检测出传感器
char DS18B20RST(void)
{
//输入程序代码  DS18B20
 DS18B20=0;
 delayNus(88);//20+58*8=484uS
 DS18B20=1;
 delayNus(6);
 if(!DS18B20){delayNus(58); return 0;} //返回正确
  delayNus(58);//超时计时
 return 1;//返回错误

}

unsigned char DS18B20read()
{
//输入程序代码
 EA=0;//读时序不能被中断
 for(iii=8;iii>0;iii--)
 {
  DS18B20=0;
  for(jjj=0;jjj<2;jjj++);//10uS
  DS18B20=1;
  temp1>>=1;
  if(DS18B20) temp1|=0x80;//else temp1&=0x7f;

  delayNus(10);//min:60us  max:120us ,here:88us
 }
 EA=1;
 delayNus(1);//don't care
 return temp1;
}

void DS18B20write(unsigned char dat)
{
//输入程序代码
 EA=0;//读时序不能被中断
 temp1=dat;
 for(iii=8;iii>0;iii--)
 {
  DS18B20=0; DS18B20=0;
  for(jjj=0;jjj<2;jjj++);//10us
  if(temp1&0x1) DS18B20=1;//else DS18B20=0;
  temp1>>=1;
  delayNus(6);//min:40us  max:100us ,here:60us
  DS18B20=1;
  delayNus(5);//don't care
 }
 delayNus(10);//don't care
 EA=1;
}


共17条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]