2301_78364727 2024-06-21 20:18 采纳率: 90.9%
浏览 6
已结题

有关AT89C51单片机问题

求:在AT89C51单片机,怎么实现任意路AD转换来控制数码管走”8“的速度
第一段代码是之前实现AD转换,光敏,热敏这些显示到数码管上的

#include <REGX51.H>
//---IO¿Ú¶¨Òå---//
sbit DOUT = P3^7;      //Êä³ö
sbit CLK  = P3^6;      //ʱÖÓ
sbit DIN  = P3^4;      //ÊäÈë
sbit CS   = P3^5;      //Ƭѡ 

unsigned char 8 =0xFF;//1111 1111


void Delay(unsigned int xms)//ÑÓʱº¯Êý
{
    unsigned char i, j;
    while(xms--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}
unsigned char showTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//0~9£¬ÊýÂë¹ÜÉÏÏÔʾ
void show(unsigned char Location,unsigned char Number,unsigned char d){//¸ù¾Ý´«ÈëµÄλÖã¬Êý×ÖºÍСÊýµã£¬ÔÚÊýÂë¹ÜÉÏÏÔʾ
    switch(Location)        
    {
        case 1:P2_4=0;P2_3=0;P2_2=0;break;
        case 2:P2_4=0;P2_3=0;P2_2=1;break;
        case 3:P2_4=0;P2_3=1;P2_2=0;break;
        case 4:P2_4=0;P2_3=1;P2_2=1;break;
        case 5:P2_4=1;P2_3=0;P2_2=0;break;
        case 6:P2_4=1;P2_3=0;P2_2=1;break;
        case 7:P2_4=1;P2_3=1;P2_2=0;break;
        case 8:P2_4=1;P2_3=1;P2_2=1;break;
    }
        if(d == 0){
            P0=showTable[Number];
        }
        else{
            P0=showTable[Number]|0x80;//0x80=10000000,Óë²Ù×÷£¬ÈôÔ­À´Îª1Ôò»¹ÊÇ1£¬Í¬Ê±µãÁÁСÊýµã
        }            
    Delay(1);
    P0=0x00;
}


void SPI_Start(void)
{
    CLK = 0;//ʱÖÓÐźÅΪµÍµçƽ
    CS  = 1;//ƬѡÐźÅδѡÖÐÍⲿÉ豸
    DIN = 1;//±íʾ·¢Ë͵ÄÊý¾ÝλÊÇ1£¬Êý¾ÝÊäÈë
    CLK = 1;//ʱÖÓÐźÅΪ¸ßµçƽ£¬ÔÚʱÖÓÉÏÉýÑØ£¬¿ÉÄÜ»á¶ÁÈ¡ÉÏÃæµÄÐÅÏ¢
    CS  = 0;        
}

void SPI_Write(unsigned char dat)//ÏòÍⲿÉ豸·¢ËÍÊý¾Ý
{
    unsigned char i;
    CLK = 0;//ÉèΪ0£¬¿ªÊ¼Ò»¸öÖÜÆÚ
    for(i=0; i<8; i++)//Ñ­»·8´Î£¬·¢ËÍ8λ
    {
        DIN = dat >> 7;//·¢Ë͵ÄÊý¾ÝÓÒÒÆ7λ£¬Ã¿´Î¶¼·¢×î¸ßλ
        dat <<= 1;//ÔÙ×óÒÆ£¬ÎªÏÂÒ»´Î·¢ËÍÊý¾Ý×ö×¼±¸
        CLK = 0;//¿ªÊ¼Ò»¸öÖÜÆÚ

        CLK = 1;//½áÊøÒ»¸öÖÜÆÚ

    }
}

unsigned int SPI_Read(void)//ÿ¶Áһ룬¾Í×óÒÆ1λ,×îжÁÈ¡µÄ¼Óµ½×îµÍλ
{
    unsigned int i, dat=0;
    CLK = 0;//×¼±¸¶ÁÈ¡
    for(i=0; i<12; i++)//¶ÁÒ»¸ö12λµÄÎÞ·ûºÅÕûÊý
    {
        dat <<= 1; 

        CLK = 1;//×¼±¸¿ªÊ¼ÐµÄÖÜÆÚ
        CLK = 0;

        dat |= DOUT;//½«DOUTµÄֵͨ¹ý»òÔËËã¼Óµ½×îµÍλ

    }
    return dat;    //·µ»Ø¶ÁÈ¡µÄ
}

unsigned int SPI(unsigned char dat){
    SPI_Start();
    SPI_Write(dat);
    return SPI_Read();
}


unsigned int ADvalue,i;

int main(){
                                      
    while(1){
        ADvalue=SPI(0xA4);//âÃô0xA4 µçλÆ÷ 0x94 ÈÈÃô0xD4
        for(i=0;i<40;i++){
            show(1,ADvalue/1000%10,0);//ǧλ
            show(2,ADvalue/100%10,1);//°Ùλ
            show(3,ADvalue/10%10,0);//Ê®
            show(4,ADvalue%10,0);//¸ö
        }
    }
    
}
  • 写回答

10条回答 默认 最新

  • 妄北y 嵌入式领域优质创作者 2024-06-21 20:19
    关注

    以下参考免费微信小程序:皆我百晓生 作答,并由妄北y整理回复。

    在AT89C51单片机上实现任意路AD转换来控制数码管走“8”的速度,首先需要理解你已有的代码。你的代码已经实现了通过SPI接口与一个AD转换器通信,获取AD转换的结果,并将其显示在数码管上。接下来,我们需要做的是利用这个AD值来控制显示“8”的速度。

    这里有几个关键步骤:

    1. 获取AD值:你的代码中已经实现了通过SPI读取AD转换结果的功能。
    2. 处理AD值:根据AD值来调整显示“8”的速度。这通常涉及到对AD值进行缩放或映射到一个特定的时间间隔。
    3. 控制数码管显示:使用show函数来控制数码管显示数字“8”,并根据AD值调整显示速度。

    下面是一个简化的示例,展示如何根据AD值来调整“8”的显示速度:

    #include <REGX51.H>
    
    // ...(省略已有的代码)
    
    // 将AD值映射到延时函数的参数
    unsigned int mapADToDelay(unsigned int ad_value) {
        // 假设AD值的范围是0到1023
        // 将这个范围映射到10到1000的范围,用于Delay函数的参数
        // 可以根据需要调整映射函数
        return (ad_value * 9 + 5) / 10; // 简单的线性映射
    }
    
    int main() {
        unsigned int ADvalue, delay_time, i;
    
        while(1) {
            ADvalue = SPI(0xA4); // 读取AD值
    
            // 根据AD值计算延时时间
            delay_time = mapADToDelay(ADvalue);
    
            // 显示数字“8”
            for(i = 0; i < 4; i++) {
                show(1, 8, 0); // 显示“8”的千位
                Delay(delay_time); // 根据AD值调整延时
                show(2, 8, 0); // 显示“8”的百位
                Delay(delay_time);
                show(3, 8, 0); // 显示“8”的十位
                Delay(delay_time);
                show(4, 8, 0); // 显示“8”的个位
                Delay(delay_time);
            }
        }
    }
    

    在这个示例中,mapADToDelay函数负责将AD值映射到一个适合Delay函数的参数。这个映射可以根据你的具体需求进行调整。然后,在main函数的循环中,我们使用这个映射后的值来控制显示“8”的速度。

    请注意,这个示例假设AD值的范围是0到1023,并且Delay函数的参数是以毫秒为单位的。你可能需要根据你的具体情况调整这些值。此外,show函数和Delay函数的实现也需要根据你的硬件和需求进行相应的调整。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(9条)

报告相同问题?

问题事件

  • 系统已结题 6月29日
  • 已采纳回答 6月21日
  • 创建了问题 6月21日

悬赏问题

  • ¥100 matlab2009 32位一直初始化
  • ¥15 Expected type 'str | PathLike[str]…… bytes' instead
  • ¥15 为什么在iis上部署网站,服务器可以访问,但是本地电脑访问不了
  • ¥15 三极管电路求解,已知电阻电压和三级关放大倍数
  • ¥15 ADS时域 连续相位观察方法
  • ¥15 Opencv配置出错
  • ¥15 关于模型导入UNITY的.FBX: Check external application preferences.警告。
  • ¥15 气象网格数据与卫星轨道数据如何匹配
  • ¥100 java ee ssm项目 悬赏,感兴趣直接联系我
  • ¥15 微软账户问题不小心注销了好像