lclbf 发表于 2023-5-12 11:31:02

本帖最后由 lclbf 于 2023-5-13 08:15 编辑

第二十四集:比较器
利用运算放大器的同相输入端高于反向输入端的电压输出高电平,同相输入端低于反向输入端的电压输出低电平,实现电压比较;STC32单片机把这个功能集成到单片机里面,用硬件来实现。
具体电路如下:

在学习是需要2个问题:
1、按照视频里面用LED0,不能控制LED0。只能用P40 = 0;P60 = 0;去控制LED0;


2、开始电位器W1调到最低位置,P37口为0V,灯不会亮,要把电位器W1调到最上面再调下来灯才会亮。我理解为:理论上

只要是P37口低于1.19V灯就会亮才对。实际中为啥会出现这样的问题,没有想明白。

实验代码如下:

lclbf 发表于 2023-5-13 08:18:40

本帖最后由 lclbf 于 2023-5-13 08:24 编辑

lclbf 发表于 2023-5-12 11:31
第二十四集:比较器
利用运算放大器的同相输入端高于反向输入端的电压输出高电平,同相输入端低于反向输 ...
上面提到的问题1的问题找到原因了,是我显示部分的代码问题。显示部分我有两个刷新代码,用错了,所以功能不对。
有问题的代码如下:
/*****************************************************
函数名称:SEG_LED_Fre
函数功能:刷新数码管
入口参数:无
函数返回:无
当前版本:VER1.0
修改日期:2023.5.2
当前作者:
其他备注:
*******************************************************/
void SEG_LED_Fre(void)
{
      static u8 num = 0;
      
      Time_Count++;                                                 //1毫秒计数加1
      if(Time_Count >= 500) //500ms灯闪烁
      {
                blink = !blink;                                           //灯闪烁
                Time_Count = 0;                                    //毫秒计数清零
      }
      
      if(num <= 7)                                                   //8位数码管的刷新
      {
                LEDPower = 1;                                       //关闭LED的电源
                SEG_COM = SEG_W;                     //选择相应的数码管的位
                if(blink_bit == num)                              //对应位数码管
                {
                        if(blink == 0)                                  //灯亮
                        {
                              SEG_SEG = SEG_D];      //需要显示的数字的段码
                        }
                        else                                             //灯熄灭
                        {
                              SEG_SEG =0xff;                  //段码不显示
                        }
                }
                else
                {
                        SEG_SEG = SEG_D];      //需要显示的数字的段码
                }                        
      }
      
      else if(num <= 8)//LED的刷新
      {
                SEG_COM = 0xff;                                 //关闭所有数码管
                LEDPower = 0;                                    //打开LED的电源
                SEG_SEG = LED_DATA;                        //输出LED的状态
      }
      
      else
      {
                SEG_COM = 0xff;                              //关闭数码管
                LEDPower = 1;                                 //关闭LED的电源
                SEG_SEG = 0xff;                               //关闭所有输出
      }
      
      num++;                                                 //计数加1
      if(num >= 10)                                        //计数大于10
                num = 0;                                       //计数清零
}


正确的代码应该是下面的:
/*****************************************************
函数名称:SEG_LED_Fre
函数功能:数码管刷新
入口参数:无
函数返回:无
当前版本:VER1.0
修改日期:2023.4.19
当前作者:
其他备注:
*******************************************************/
void SEG_LED_Fre()
{
      static num = 0;
      
      if(num <= 7)                                                 //8位数码管刷新
      {
                LEDPower = 1;                                     //关闭LED
                SEG_SEG = SEG_D];    //段码给P6口
                SEG_COM = SEG_W;                  //第一位数码管显示
      }
      else if(num <= 8)                                        //LED刷新
      {
                SEG_COM = 0xff;                               //关闭数码管
                LEDPower = 0;                                  //打开LED总电源
                SEG_SEG = LED_DATA;                     //点亮对应的LED
      }
      else
      {
                LEDPower = 1;                               //关闭LED
                SEG_COM = 0XFF;                         //关闭数码管
                SEG_SEG = 0XFF;                         //关闭P6口
      }
      
      num++;                                                                           //段码数组值自加
      if(num >= 10)                                                                                          //加到9归0
      num = 0;
}

修正后的代码如下:

zjwzyqwzw 发表于 2023-5-14 08:16:25

666

lclbf 发表于 2023-5-14 13:59:44

zjwzyqwzw 发表于 2023-5-14 08:16
666

谢谢鼓励!

lclbf 发表于 2023-5-15 14:12:05

本帖最后由 lclbf 于 2023-5-15 14:21 编辑

第二十五集:EEPROM
   EEPROM的学习:写程序注意,写前要先擦除,也就是要先全部写1.冲哥视频讲了单字节的操作。没有单独冲EEPROM,借用单片机的FLASH来当EEPROM,
EEPROM的大小,在下载程序的时候可以根据自己的需要来选择大小(不知道我这样理解对不对)。冲哥视频和规格书都讲的选64K,如下图所示:


还有要注意的是:下载程序若是选择为1K,地址不能大于1023,如下:


      dat = EEPROM_read_n(1023);        //读取e2数据 eeprom是1K最大值为1023
        EEPROM_SectorErase(1023);        //初始化e2数据,把指定地址的EEPROM扇区擦除
        EEPROM_write_n(1023,dat+1);//将当前数据+1之后重新写入



实验程序如下:




lclbf 发表于 2023-5-15 14:28:10

本帖最后由 lclbf 于 2023-5-15 14:34 编辑

lclbf 发表于 2023-5-12 11:31
第二十四集:比较器
利用运算放大器的同相输入端高于反向输入端的电压输出高电平,同相输入端低于反向输 ...
对于比较器,我说的第二个问题:
   开始电位器W1调到最低位置,P37口为0V,灯不会亮,要把电位器W1调到最上面再调下来灯才会亮。我理解为:理论上只要是P37口低于1.19V灯就会亮才对。实际中为啥会出现这样的问题,没有想明白。
对于这个问题我理解有错,没有好好看规格书,在QQ交流群冲哥回复了我,我又去看了规格书,条件是要上升沿和下降沿才能触发,没有高电平和低电平触发,所以要去调电位器,让他产生一个变化的上升沿或者
下降沿。

lclbf 发表于 2023-5-18 17:07:35

本帖最后由 lclbf 于 2023-5-18 17:16 编辑

第二十六集:单总线控制DS18B20
   电路图如下:


   DS18B20做温度传感器测试温度,用途广泛,电路简单,元件就3个脚,电源供电,地和输出。供电用104电容滤波,保证工作稳定,
通过本视频的学习,明白了啥是底层函数,啥是接口函数,啥是用户功能函数。

//---------------底层驱动---------------/
void DS18b20_Reset(void);                                //复位
void DS18b20_Write_0(void);                        //写逻辑0码
void DS18b20_Write_1(void);                        //写逻辑1码
bit DS18b20_Read(void);                                        //读取电平

//---------------接口函数---------------/
void DS18b20_WriteByte(u8 dat);        //写一个字节
u8 DS18b20_ReadByte(void);                        //读取一个字节

//---------------用户功能函数---------------/
u16 DS18b20_ReadTemp(void);                        //读取并且换算温度,并返回


通过本视频学习实现了打印输出温度和数码管显示温度。

if(MinusFlag == 1)
                                {
                                        SEG0 = 20;                                                 //负数符号
                                        SEG1 = Temp/100%10;                //十位
                                        SEG2 = Temp/10%10+10; //个位带小数点
                                        SEG3 = Temp/1%10;                        //十分位
                                        printf( "当前温度:-%.01f\r\n",(float)((float)Temp/10) );
                                }
                                else
                                {
                                        SEG1 = Temp/100%10;                //十位
                                        SEG2 = Temp/10%10+10; //个位带小数点
                                        SEG3 = Temp/1%10;                        //十分位
                                        printf( "当前温度:%.01f\r\n",(float)((float)Temp/10) );
                                }


程序压缩如下附件:

lclbf 发表于 2023-5-18 17:18:06

本帖最后由 lclbf 于 2023-5-24 10:34 编辑

第二十七集:软件模拟SPI通信
SPI通信是属于双工通信。试验箱应用电路如下:



通过软件模拟SPI通信,读取U11的ID号。
关键函数如下:
vovoid SPI_Init(void)void SPI_WriteByte(u8 dat)u8 SPI_ReadByte(void)id

实验程序压缩包如下:




lclbf 发表于 2023-5-24 08:14:18

本帖最后由 lclbf 于 2023-5-24 10:44 编辑

第二十八集:硬件SPI

      本视频介绍了用硬件SPI实现都芯片ID的读取,和用USART1实现SPI功能来读取芯片ID,冲哥实验是通过打印输出来验证的,我在上面还加入了数码管显示。

SPI 相关寄存器如下:







程序代码如下压缩包:


lclbf 发表于 2023-5-24 08:23:56

第二十九集:SPI的应用,SPI读写W25X40CL
   实际应用中,不单要对单片机的SPI通信协议熟悉,还要对对应的外挂芯片的手册熟悉,才能更好的实现目的,现在很多芯片资料是英文的,对于我来说是个难点,冲哥视频说了借助翻译软件,看关键部分。
实验代码如下压缩包:
页: 1 2 3 4 5 6 [7] 8
查看完整版本: 冲哥视频学习笔记