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

第一次:环境的创立 | 送实验箱

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 6 天前 | 显示全部楼层
// ----------------------- p10端口闪烁        -----------------------       
        if( P10_STATE == 0 )
                LED40_SetBit(1,0);
        else
                LED40_ClrBit(1,0);
       
        P10_STATE = !P10_STATE;
}


闪烁就是在高低电平切换,最容易实现的


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 6 天前 | 显示全部楼层
再来看我们下面虚拟的数码管:


截图202508182204156647.jpg
截图202508182204566620.jpg
截图202508182206175489.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 6 天前 | 显示全部楼层
任务2:左边数码管显示P32按下次数
右边数码管显示P33按下次数

这个要学会按键按下次数的计算......

其实还是用常整数可能会比字符串更方便

u32 KEY_Count = 0;

// 任务2:左边数码管显示P32按下次数, 右边数码管显示P33按下次数
void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *10000 + KEY2_COUNT;
       
        SEG7_ShowLong( KEY_Count ,10);
       
}


这个不好理解,有压缩饼干的味道..........

当然,要从这里入手:


u16 KEY1_COUNT = 0;                //P32按钮计数
u16 KEY2_COUNT = 0;                //P33按钮计数

void KEY_Task(void)
{
// ------------P32按钮计数------------       
        if( P32 == 0 )
        {
                Key_Vol++;
                if( Key_Vol==5 )
                {
                        KEY1_COUNT++;
                }
        }
        else
        {
                Key_Vol = 0;
        }
       
// ------------P33按钮计数------------               
        if( P33 == 0 )
        {
                Key_Vol_2++;
                if( Key_Vol_2==5 )
                {
                        KEY2_COUNT++;
                }
        }
        else
        {
                Key_Vol_2 = 0;
        }       
       
}




回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
又遇到一个奇诡的问题:


下载的时候,ISP打开编译好的 .HEX文件的时候,说文件大学超出范围:

截图202508190757386880.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
还有个小问题:

这里原来是乘以10000


void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *10000 + KEY2_COUNT;  //2个次数整合为1个方便显示
       
        SEG7_ShowLong( KEY_Count ,10);
       
}


实验后,发现改成1000,效果更好:


void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *1000 + KEY2_COUNT;  //2个次数整合为1个方便显示
       
        SEG7_ShowLong( KEY_Count ,10);
       
}

可以解决P32按10次后乱码的问题,当然也不是彻底解决......


截图202508190809526455.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
u16 KEY1_COUNT = 0;                //P32按钮计数
u16 KEY2_COUNT = 0;                //P33按钮计数

本来2个按键起码按65534次才出问题,但是实际上按了20多次就胡乱显示啦


P33就问题不大,主要是在P32上:

确实是65535溢出问题!

//signed long KEY_Count = 0;
//float KEY_Count = 0;
u32 KEY_Count = 0;
// 任务2:左边数码管显示P32按下次数, 右边数码管显示P33按下次数
void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *1000 + KEY2_COUNT;  //2个次数整合为1个方便显示
        //printf("按键按下次数\xfd:%d 次 \r\n",(signed long)KEY_Count);

            SEG7_ShowLong( KEY_Count ,10);
          //SEG7_ShowFloat(KEY_Count);
}


我直觉问题是在显示上,本来想看看printf("按键按下次数\xfd:%d 次 \r\n",(signed long)KEY_Count);
KEY_Count超过65534之后是多大?

但是 USB-CDC串口不知道从ai8051u哪里发出的打印指令一直在回打:

只能先放一下,暂时*1000 ,这样P33可以按999次,P32最大按64次!




截图202508190830305939.jpg
截图202508190915424564.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
当然,我发现还有


int SEG7_ShowString(const char *fmt, ...); 函数


去手册看看?

手册指引我们去:
上面调试仿真接口函数的详细帮助信息请参考下载软件中的“接口协议及帮助”


功能2:
在数码管上显示4字节长整型数
命令格式:
37H 53H 45H 47H 4CH x1 x2 00H d1 d2 d3 d4
命令说明:
第1~4字节:
命令头
第5字节:
功能选择(4CH显示长整型数)
第6字节:
数据存储格式(0:LE, 1:BE)
第7字节:
显示进制(02H:二进制, 0AH:十进制, 10H:十六进制)
第8字节:
保留
第9~12字节:
长整型数的存储数据
示例1:
发送37H 53H 45H 47H 4CH 00H 10H 00H 12H 34H 56H 78H
在数码管上会显示78564312
示例2:
发送37H 53H 45H 47H 4CH 01H 10H 00H 12H 34H 56H 78H
在数码管上会显示12345678
库函数声明:
void SEG7_ShowLong(long n, char radix);//n:长整型数 radix:进制
库函数调用:
SEG7_ShowLong(0x98765432, 16);
注:
当超出显示范围时自动转为科学计数法进行显示


本来应该是对的,4字节长整型是可以正常显示的。但是:


//signed long KEY_Count = 0;
//float KEY_Count = 0;
//u32 KEY_Count = 0;
long KEY_Count = 0;

// 任务2:左边数码管显示P32按下次数, 右边数码管显示P33按下次数
void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *100 + KEY2_COUNT;  //2个次数整合为1个方便显示
        //printf("按键按下次数\xfd:%d 次 \r\n",(signed long)KEY_Count);

            SEG7_ShowLong((long) KEY_Count ,10);
          //SEG7_ShowFloat(KEY_Count);
}


4字节长整型如何正确定义?u32不行么  unsigned long KEY_Count = 0; u32 KEY_Count = 0;


应该都没问题啊?反正一超出65534就乱了,根源应该是计数器溢出中断?

65536代表的是一个16位计数器的最大值。这个计数器由高8位(TH0)和低8位(TL0)组成,可以存储2^16=65536个数。当计数器从65536开始计数时,经过一段时间后会溢出并产生中断。


所以根本问题不是显示!

我们验证一下:


//signed long KEY_Count = 0;
//float KEY_Count = 0;
//u32 KEY_Count = 0;
unsigned long KEY_Count = 0;

// 任务2:左边数码管显示P32按下次数, 右边数码管显示P33按下次数
void TASK_2( void )
{
        KEY_Count = KEY1_COUNT *100 + KEY2_COUNT;  //2个次数整合为1个方便显示
        //printf("按键按下次数\xfd:%d 次 \r\n",(signed long)KEY_Count);
                KEY_Count = 88888888;
            SEG7_ShowLong((long) KEY_Count ,10);
          //SEG7_ShowFloat(KEY_Count);
}








截图202508190944155776.jpg
截图202508191001553008.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
当然,实际上65535也是够用的


我们乘以100

这是P32可以按655次,P33反正可以进位,就算不进位也有99次,混过去是可以的...........
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
最后就是拟键盘!


任务3:按下数字按键在数码管显示对应的按键数字!
例:按下按键0数码管显示0;

先学会用  extern 关键字:

extern u32 REC_NUM;  //变量是在io.c建立的
//这个变量要在其他函数使用,就要加extern
//关键字,并且这里不能赋值,就是不能这样:
//extern u32 REC_NUM=0;只能extern u32 REC_NUM;
//意思是我已经在别的地方定义好了。加了extern
//编译器就会自动去别的地方找到这个变量

看看主函数:

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

    IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
       
        while(1)
        {
               
        if (bUsbOutReady)                                                        //如果接收到了数据
        {
                        REC_NUM = UsbOutBuffer[5]-48;
                        //我们接受的数据在UsbOutBuffer里面
/*功能:在虚拟键盘上按键然后发送相应的键值到设备
命令格式:4EHH 59H 50H 00H x1 00H 00H
命令说明:
?
第1~4字节:命令头
第5字节:保留
第6字节:按键键值
第7~8字节:保留
我们需要第6个字节(从0数是第5个)
UsbOutBuffer[5]-48;-48就是ASCII编码问题,我们
要直接显示数字,不需要显示ASCII编码
上位机发0的编码48过来,我们直接发0回去显示
用void TASK_3( void )完成任务
示例:接收到4BH 45H 59H 50H 00H 30H 00H 00H
表示数字键0被按下*/
                       
           // USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                       
            usb_OUT_done();                                                        //
        }
                Task_Pro_Handler_Callback();                                //执行功能函数

        }
}


u32 REC_NUM是在io.c里定义赋初值的,顺便写好任务3函数void TASK_3( void )



u32 REC_NUM = 0;

// 任务3:按下数字按键在数码管显示对应的按键数字!
void TASK_3( void )
{
        SEG7_ShowLong( REC_NUM ,10);
}





截图202508191126189319.jpg
截图202508191228545639.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 5 天前 | 显示全部楼层
课后练习,好像很难

不过,我们已经学完了十集,还算可以啦,没有间断,一鼓作气就算合格


今天到此为止啦
截图202508191232383549.jpg
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-24 09:21 , Processed in 0.133916 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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