找回密码
 立即注册
楼主: YangHY

第一课 序言《AI8051U的特点》

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:10:19 | 显示全部楼层
在.h里定义个DS18b20的引脚:

#define DQ  P33

extern u8  MinusFlag ;                        //如果等于0 ,正数;等于1,负数
extern u32 Temp_18b20;                        //最终的温度,放大了10000倍

同时声明在.c里定义的2个变量是全局变量


@24.000MHz,480微秒

@24.000MHz,60微秒

@24.000MHz,1微秒

这么短的时间,用什么定时器,直接软件延时算啦!
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:24:17 | 显示全部楼层
接着我们写0:

//写逻辑0(输出0保持60us+,输出1保持1us+)
void DS18B20_Write_0(void)
{
        DQ = 0;
        Delay60us();
        DQ = 1;
        Delay1us();
        Delay1us();
}


我们写0的意思的单片机向DS18B20写入逻辑0
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:31:02 | 显示全部楼层
写逻辑1和写0差不多:

//写逻辑1(输出0保持1us+,输出1保持60us+)
void DS18B20_Write_1(void)
{
        DQ = 0;
        Delay1us();
        Delay1us();
        DQ = 1;
        Delay60us();
}
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:32:44 | 显示全部楼层
读0,读1 就有点不同,要返回值:

//读逻辑0/1(输出0保持1us+,输出1保持1us+,读取当前电平,延时60us)
bit DS18B20_Read(void)
{
        bit state = 0;
       
        DQ = 0;
        Delay1us();
        Delay1us();       
        DQ = 1;
        Delay1us();
        Delay1us();       
        state = DQ;                //暂时保存这个DQ的数值
        Delay60us();
       
        return state;
}

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:50:21 | 显示全部楼层
接着我们读1个字节:

/读1字节(先读到的是低位,后读到的是高位)
u8 DS18B20_ReadByte(void )
{
        u8 i;
        u8 dat=0;                                //数据暂存,
       
        for(i=0;i<8;i++)                //循环读取八次
        {
                dat >>= 1;
                if( DS18B20_Read() )        //如果读回来的是逻辑1   //0000 0000  ->1000 0000 -> 0100 0000
                {
                        dat |= 0x80;
                }
                else
                {
                }
        }
        return dat;
}

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 11:50:50 | 显示全部楼层
写1个字节:

//写1字节(先输出低位,在输出高位)
void DS18B20_WriteByte( u8 dat )
{
        u8 i;
        for(i=0;i<8;i++)
        {
                if( dat & 0x01 )        //最低位是1.发逻辑1电平
                {
                        DS18B20_Write_1();
                }
                else                                //否则.发逻辑0电平
                {
                        DS18B20_Write_0();
                }
                dat >>= 1;                        //dat = (dat>>1);
        }
}
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 12:06:50 | 显示全部楼层
好了,基础底层函数都写好了,开始读温度:

//复位-CCH-44H-等待-复位-CCH-BEH-读取2字节温度数据-换算)
void DS18B20_ReadTemp(void)
{
        u8 TempH = 0;
        u8 TempL = 0;
        u16 Temp = 0;
//---------------------发送检测命令---------------------        
        DS18B20_Reset();                        //1.发送复位命令
        DS18B20_WriteByte(0xcc);        //2.跳过ROM命令
        DS18B20_WriteByte(0x44);        //3.开始转化命令
        while( !DQ );                                //4.等待这个引脚变成高电平
        
//---------------------发送读取命令---------------------        
        DS18B20_Reset();                        //1.发送复位命令
        DS18B20_WriteByte(0xcc);        //2.跳过ROM命令
        DS18B20_WriteByte(0xBE);        //3.开始转化命令        
        TempL = DS18B20_ReadByte(); //读取低字节温度
        TempH = DS18B20_ReadByte(); //读取高字节温度        
        
        if( TempH & 0x80 )                        //如果最高位是1,这个就是负数
        {
                MinusFlag = 1;
                Temp = (((u16)TempH << 8) | ((u16)TempL << 0));
                Temp = (~Temp) +1;
                Temp_18b20 = (u32)Temp*625;   //最终的温度,放大了10000倍,就可以用整型变量
        }
        else
        {
                MinusFlag = 0;
                Temp = (((u16)TempH << 8) | ((u16)TempL << 0));
                Temp_18b20 = (u32)Temp*625;   //最终的温度,放大了10000倍,就可以用整型变量
        }
}

注意把浮点数改成32位整数的技巧,并且保证不会溢出(放大了10000倍)
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 12:41:01 | 显示全部楼层
那么,读出来的温度,怎么显示在数码管上?

先写个函数:

void SEG_Show_U32(u32 num)
{
        u8 i;
        for(i=0;i<8;i++)
        {
                passward[7-i] = num%10;
                num /= 10;
        }
}
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 12:46:09 | 显示全部楼层
我们先调用一下,把读到的温度值,写到数码管显示缓冲区数组!

这个放在主函数调用:

void main(void)
{
        Sys_init();                                                                                //系统初始化
        usb_init();                                     //USB CDC 接口配置

    IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
//        Init_595();
//        INT1_Init();                                                                        //外部中断1初始化
//        P3_IO_Init();                                                                        //IO中断初始化
//        P4_IO_Init();
       
        //TIM1_Count_Init();
        Timer1_Init();
       
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
//        WDT_CONTR = 0X24;
       
        while(1)
        {
               
        if (bUsbOutReady)                                                        //如果接收到了数据
        {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                       
            usb_OUT_done();                                                        //
        }
                Task_Pro_Handler_Callback();                                //执行功能函数
               
                SEG_Show_U32(Temp_18b20);   //循环的把Temp_18b20的值写入passward[8],要来显示{0,  1,   1,     SEG_Task},             //显示数码管

        }
}
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2026-03-03 08:35:54
已绑定手机

5

主题

1092

回帖

1374

积分

金牌会员

积分
1374
发表于 2026-2-11 12:55:30 | 显示全部楼层
接着有个反复调试修改错误的过程

最终得到:

截图202602111255411699.jpg
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-6 06:14 , Processed in 0.116888 second(s), 80 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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