这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » blueapple2的DIY进程贴-按键扫描显示实验(视频)

共21条 2/3 1 2 3 跳转至
助工
2011-11-29 13:34:52     打赏
11楼
板子基本焊好,不用的元件暂不焊。下一步开始做实验。

助工
2011-12-02 08:46:20     打赏
12楼
本周事情实在太多了,没时间搞。

助工
2011-12-04 16:04:34     打赏
13楼
实验1:LED数码管数字、字母显示,视频怎么上?

助工
2011-12-04 16:17:39     打赏
14楼

先上代码:
/*****************************************************************************
*         LED数码管显示演示程序                                                *
*         在8个LED数码管上依次显示1,2,3,4,5,6,7,8                              *
          P2口(片选位):(采用的P2.0-P2.2控制三线八线译码器74HC138)
          0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
           位1  位2  位3  位4  位5  位6  位7  位8

          P0口(数据位):
          0x3f 0x06 0x5b 0x4f 0x66 0x6d 0x7d 0x07 0x7f 0x6f
            0    1    2    3    4    5    6    7    8    9
          0x77 0x7c 0x39 0x5e 0x79 0x71
            A    B    C    D    E    F
*******************************************************************************/
#include <reg51.h>         //包含头文件
#include <intrins.h>        //包含移位函数头文件
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

uchar code segment[]={0x3f ,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77 ,0x7c ,0x39 ,0x5e ,0x79 ,0x71 };//此数组为 0-f
uchar code select[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位选代码


void delay(uint t)
{
  uint x,y;
 for(x=t;x>0;x--)
   for(y=110;y>0;y--);
}

/****************************************************
函数:display()
功能:动态显示数码管0-F
参数:duan段选,wei位选,time延时时间设定
说明:无
时间2011.12.3
****************************************************/

void display(uint duan,wei,time)
 {
   P2=select[wei];
     P0=segment[duan];
      delay(time); 
      P0=0x00;
 }
void display_num(ulong num)
 {
     uint i;
  ulong curnum;
  ulong tmpnum;
  uint k=5;
  i=8 ;
  tmpnum=num;
  do
  {
      curnum=tmpnum % 10;
   tmpnum=tmpnum / 10;
   display(curnum,i-1,k) ;
      i--  ;
        }
  while(i>0 && tmpnum>0);
 }

 

 void main()
 {
   uint i, k,d,t=5;
   ulong l;
   while(1) 
   {
      for (k=0;k<2;k++)
      {
         for (d=0;d<8;d++)
   {
            for (i=0;i<500;i++)  //持续一定时间
            {
               display(7*k+d,d,t) ;
         }
       }
    }
    delay(1000)  ;
       l=12345678;
       for (i=0;i<500;i++)
       {
           display_num(l) ;
    }
    delay(1000)  ;
       l=23456789;
       for (i=0;i<500;i++)
       {
          display_num(l) ;
    }
       delay(1000)  ;

    }
 
 }

 


助工
2011-12-04 16:37:11     打赏
15楼

下载程序有点周折,STC比较挑剔,原有的USB转串口线不能用,开始以为串口部分有问题,经反复检查没发现问题,后拿到台式机上试,可以下载,从新买了一条HL-340芯片的,可以下载了。下载时要先点程序中的下载按钮,再上电,否则不易成功。


助工
2011-12-05 13:25:10     打赏
16楼

LED数码管显示


助工
2011-12-11 17:32:49     打赏
17楼

助工
2011-12-11 17:40:14     打赏
18楼

按键扫描实验代码:
/*****************************************************************************
程序名称:矩阵键盘扫描显示键值
简要说明:P3口接矩阵键盘:低四位行,高四位列
          LED数码管                             *
          P2口(片选位):(采用的P2.0-P2.2控制三线八线译码器74HC138)
          0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
           位1  位2  位3  位4  位5  位6  位7  位8

          P0口(数据位):
          0x3f 0x06 0x5b 0x4f 0x66 0x6d 0x7d 0x07 0x7f 0x6f
            0    1    2    3    4    5    6    7    8    9
          0x77 0x7c 0x39 0x5e 0x79 0x71
            A    B    C    D    E    F
*******************************************************************************/
#include <reg51.h>         //包含头文件
#include <intrins.h>        //包含移位函数头文件
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

uchar code segment[]={0x3f ,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77 ,0x7c ,0x39 ,0x5e ,0x79 ,0x71 };//此数组为 0-f
uchar code select[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位选代码
uchar key_val=0;   //定义键值,初始默认为0


void delay(uint t)
{
  uint x,y;
 for(x=t;x>0;x--)
   for(y=110;y>0;y--);
}
 
/****************************************************
函数:display()
功能:动态显示数码管0-F
参数:duan段选,wei位选,time延时时间设定
说明:无
时间2011.12.3
****************************************************/

void display(uint duan,wei,time)
 {
   P2=select[wei];
     P0=segment[duan];
      delay(time); 
      P0=0x00;
 }
void display_num(ulong num)
 {
     uint i;
  ulong curnum;
  ulong tmpnum;
  uint k=5;
  i=8 ;
  tmpnum=num;
  do
  {
      curnum=tmpnum % 10;
   tmpnum=tmpnum / 10;
   display(curnum,i-1,k) ;
      i--  ;
        }
  while(i>0 && tmpnum>0);
 }

/*****按键扫描*****/
void Check_Key(void)
{
 unsigned char row,col,tmp1,tmp2;
    tmp1 = 0x01;            //tmp1用来设置P3口的输出,取反后使P3.0~P3.3中有一个为0
    for(row=0;row<4;row++)   // 行检测
 {
        P3 = 0x0f;            // 先将P3.0~P3.3置高
        P3 =~tmp1;            // 使P3.0~P3.3中有一个为0
        tmp1*=2;             // tmp1左移一位
        if ((P3 & 0x0f) < 0x0f)    // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测
  {
      tmp2 = 0x10;     // tmp2用于检测出哪一列为0
      for(col =0;col<4;col++)   // 列检测
      {
       if((P3 & tmp2)==0x00)  // 该列如果为低电平则可以判定为该列
       {
         key_val = row*4 +col; // 获取键值,识别按键
         return;     // 退出循环
       }
       tmp2*=2;      // tmp2左移一位
            }
        }
    }
}         


 void main()
 {
//   uint i;
//   ulong l;
   while(1) 
   {
        Check_Key();
//       l=key_val;
  //     for (i=0;i<5;i++)
  //     {
           display_num(key_val) ;
//    }
//    delay(1000)  ;

    }
 
 }

 


助工
2011-12-25 10:38:15     打赏
19楼
PCF8591AD实验:

助工
2011-12-25 10:39:46     打赏
20楼

代码:     //-----------------------函数声明,变量定义------------------------
#include <reg51.h>
#include <intrins.h>
sbit SCL=P1^1;                   // 将p1.2口模拟时钟口
sbit SDA=P1^2;                   // 将p1.3口模拟数据口
bit askflag;
#define uchar unsigned char
#define uint  unsigned int
#define disdata  P0              //显示数据码输出口

sbit LCD_RS = P2^4;             
sbit LCD_RW = P2^5;
sbit LCD_EN = P2^6;
#include <lcd.h>

uint data dis[4]={0x00,0x00,0x00,0x00}; 
                          //定义3个显示数据单元和1个数据存储单元

//uchar code dis4[] = {"1- .  V  2- .  V"};
//uchar code dis5[] = {"3- .  V  4- .  V"};


#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
                 
bit   bdata SystemError;                //从机错误标志位

/*********************** PCF8591专用变量定义 ***********************/

#define PCF8591_WRITE 0x90 
#define PCF8591_READ  0x91
#define  NUM  4              //接收和发送缓存区的深度
uchar idata receivebuf[NUM];    //数据接收缓冲区

/*******************************************************************/
/*                                                                 */
/*  延时函数                                                       */
/*                                                                 */
/*******************************************************************/

void delay(int ms)
{
    while(ms--)
{
      uchar i;
  for(i=0;i<250;i++)  
   {
    _nop_();    
_nop_();
_nop_();
_nop_();
   }
}
}

/*******************************************************************/
/*                                                                 */
/*检查LCD忙状态                                                    */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
/*                                                                 */
/*******************************************************************/ 

bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result); 
 }

/******************************************************************/
/*                                                                */
/* 数据处理与显示                                                 */
/* 将采集到的数据进行16进制转换为ASCLL码。                        */
/*                                                                */
/******************************************************************/

void show_value(uchar ad_data)

{   
    dis[2]=ad_data/51;   //AD值转换为3为BCD码,最大为5.00V。
    dis[2]=dis[2]+0x30;  //转换为ACSII码
    dis[3]=ad_data%51;   //余数暂存
    dis[3]=dis[3]*10;    //计算小数第一位
    dis[1]=dis[3]/51;
    dis[1]=dis[1]+0x30;  //转换为ACSII码
    dis[3]=dis[3]%51;
    dis[3]=dis[3]*10;    //计算小数第二位
    dis[0]=dis[3]/51;                                                                             //
    dis[0]=dis[0]+0x30;  //转换为ACSII码           

//-------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//-------------------------------------------------------------------
void iic_start(void)
{ //时钟保持高,数据线从高到低一次跳变,I2C通信开始
SDA = 1;     
SCL = 1;
delayNOP();      // 延时5us 
    SDA = 0;
delayNOP();
    SCL = 0;
}
//-------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//-------------------------------------------------------------------
void iic_stop(void)
{  
SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
SCL = 1;
delayNOP();
SDA = 1;
delayNOP();
    SCL = 0;
}
//------------------------------------------------------------------
// 函数名称: iicInit_()
// 函数功能: 初始化I2C总线子程序
//------------------------------------------------------------------
 void iicInit(void)
   {
   SCL = 0;
   iic_stop();
   }  
//-------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//-------------------------------------------------------------------
void slave_ACK(void)
{
SDA = 0;  
SCL = 1;
delayNOP();
SCL = 0;
}
//-------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//-------------------------------------------------------------------
void slave_NOACK(void)

SDA = 1;
SCL = 1;
delayNOP();
SDA = 0;
    SCL = 0;  
}
//-------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//-------------------------------------------------------------------
void check_ACK(void)
{      
    SDA = 1;        // 将p1.1设置成输入,必须先向端口写1
SCL = 1;
askflag = 0;
delayNOP();   
if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志askflag
    askflag = 1;
    SCL = 0;
}
//-------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//-------------------------------------------------------------------
void IICSendByte(uchar ch)
 
{
   unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位

while(n--)

if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
   {
  SDA = 1;    // 传送位1
SCL = 1;
    delayNOP();
// SDA = 0;
SCL = 0; 
   }
else
{  
SDA = 0;    // 否则传送位0
SCL = 1;
delayNOP();
   SCL = 0;
}
ch = ch<<1;    // 数据左移一位
}
}
//-------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//-------------------------------------------------------------------
uchar IICreceiveByte(void)
{
uchar idata n=8;     // 从SDA线上读取一上数据字节,共八位
uchar tdata=0;
while(n--)
{
   SDA = 1;
   SCL = 1;
   tdata =tdata<<1;     //左移一位
    if(SDA == 1)
  tdata = tdata|0x01;   // 若接收到的位为1,则数据的最后一位置1
else 
  tdata = tdata&0xfe;   // 否则数据的最后一位置0
   SCL = 0;
 }

 return(tdata);
}
//-------------------------------------------------------------------
// 函数名称: DAC_PCF8591
// 入口参数: slave_add从机地址,n要发送的数据个数
// 函数功能: 发送n位数据子程序
//-------------------------------------------------------------------
void DAC_PCF8591(uchar controlbyte,uchar w_data)
{    

iic_start();                    // 启动I2C
delayNOP();

IICSendByte(PCF8591_WRITE);     // 发送地址位
check_ACK();                    // 检查应答位
    if(askflag == 1)
 { 
SystemError = 1;
return;                     // 若非应答,置错误标志位
     }
    IICSendByte(controlbyte&0x77); //Control byte 
check_ACK();                    //检查应答位
    if(askflag == 1)
 { 
SystemError = 1;
return;                    // 若非应答,置错误标志位
 }
    IICSendByte(w_data);        //data byte
check_ACK();                  // 检查应答位
    if(askflag == 1)
 { 
SystemError = 1;
     return;   // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }
iic_stop();         // 全部发完则停止
delayNOP();
delayNOP();
delayNOP();
delayNOP();
}
//-------------------------------------------------------------------
// 函数名称: ADC_PCF8591
// 入口参数: controlbyte控制字
// 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
//-------------------------------------------------------------------
void ADC_PCF8591(uchar controlbyte)

    uchar idata receive_da,i=0;
while(i<4)
{  

iic_start();

IICSendByte(PCF8591_WRITE); //控制字
check_ACK();
if(askflag == 1)
{
SystemError = 1;
return;
}

IICSendByte(controlbyte + i); //控制字
check_ACK();
if(askflag == 1)
{
SystemError = 1;
return;
}

    iic_start();                //重新发送开始命令
    IICSendByte(PCF8591_READ); //控制字
check_ACK();
if(askflag == 1)
{
SystemError = 1;
return;
}
 
    IICreceiveByte();   //空读一次,调整读顺序
    slave_ACK();        //收到一个字节后发送一个应答位

//while(i<4)
//{  
  receive_da=IICreceiveByte();
  receivebuf[i++]=receive_da;
  slave_ACK();       //收到一个字节后发送一个应答位
}
slave_NOACK();       //收到最后一个字节后发送一个非应答位
iic_stop();
}
//-------------------------------------------------------------------
// 函数名称: main
// 函数功能: 主程序
//-------------------------------------------------------------------
main()
{
    //uchar i,l;
 uchar l;
    delay(10);                 //延时
    LCD_init();                //初始化LCD             
  LCD_write_str(0,0,"1- .  V  2- .  V");
  LCD_write_str(1,0,"3- .  V  4- .  V");
  while(1)
  {

iicInit();               //I2C总线初始化
    ADC_PCF8591(0x04);

if(SystemError == 1)   //有错误,重新来
  {
   iicInit();   //I2C总线初始化
    ADC_PCF8591(0x04);
   }   

for(l=0;l<4;l++)
 {
        show_value(receivebuf[0]); //显示通道0       
        LCD_write_char(0,2,dis[2]);        //整数位显示
  LCD_write_char(0,3,'.');     //小数点
        LCD_write_char(0,4,dis[1]);        //第一位小数显示 
        LCD_write_char(0,5,dis[0]);        //第二位小数显示

        show_value(receivebuf[1]); //显示通道1  
        LCD_write_char(0,11,dis[2]);        //整数位显示
  LCD_write_char(0,12,'.');     //小数点
        LCD_write_char(0,13,dis[1]);        //第一位小数显示 
        LCD_write_char(0,14,dis[0]);        //第二位小数显示

        show_value(receivebuf[2]); //显示通道2           
        LCD_write_char(1,2,dis[2]);        //整数位显示
  LCD_write_char(1,3,'.');     //小数点
        LCD_write_char(1,4,dis[1]);        //第一位小数显示 
        LCD_write_char(1,5,dis[0]);        //第二位小数显示

        show_value(receivebuf[3]); //显示通道3  
        LCD_write_char(1,11,dis[2]);        //整数位显示
  LCD_write_char(1,12,'.');     //小数点
        LCD_write_char(1,13,dis[1]);        //第一位小数显示 
        LCD_write_char(1,14,dis[0]);        //第二位小数显示

      iicInit();               //I2C总线初始化  
      DAC_PCF8591(0x40,receivebuf[0]); //D/A输出

    if(SystemError == 1)   //有错误,重新来
    {
    iicInit();   //I2C总线初始化
 DAC_PCF8591(0x40,receivebuf[0]); //D/A输出
    }         

      //delay(50);                       //延时
 }

   }
}


共21条 2/3 1 2 3 跳转至

回复

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