微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > 嵌入式系统设计讨论 > 如何升华51单片机基础,成为一个出色的开发工程师。

如何升华51单片机基础,成为一个出色的开发工程师。

时间:10-02 整理:3721RD 点击:


如何升华51单片机基础,成为一个出色的开发工程师


高手问答 第14期

小编导读:
      本期高手问答(10月9日—10月17日),我们请来了《深入浅出玩转51单片机》一书的作者刘平老师,解答关于51单片机、嵌入式方面的问题。



《深入浅出玩转51单片机》一书和MGMC-V1.0实验板紧密配套,所有书里的工程案例,在51平台都能得到验证。如:
      (1)基于状态机的独立、矩阵按键检测,完美的解决了普通延时在工程项目带来的种种问题。
      (2)模块化编程,可以让其编程规范化,继而起到事半功倍的作用。
      (3)RTX51 Tiny实时操作的应用,该系统不仅能解决软件编程和串行操作的一些问题,还能为以后学习uCOS、FreeRTOS、Linux等操作系统打好基础


假如
      你正在尝试着用 单片机+视频解码+TFT彩屏,做mini电视,
      你正在尝试着使用 单片机 +A/D转换+显示,做电子负载,
      ······
      关于这些,你都可以在下面跟帖留言, 和刘平老师一起交流。
      另外,刘平老师还做过蓝牙、算法方面的项目,so,关于这方面也可以在下面提问或者是share your ideas。

     为了营造更好的问答氛围,我们不欢迎一切与主题无关的讨论、灌水和无脑喷子。

      下面欢迎大家踊跃提问。在本帖回复并 @xymbmcu (刘平老师),

       参与活动提出问题即可获得10个可用积分。



社区高手招募
     不限专业领域、不限技术方向,只要你是一个有活力并乐于分享的开发者,只要你愿意把自己的经验收获分享给大家,帮助众多从业者共同学习、共同进步,我们就欢迎你来做客社区高手问答。
      联系方式:pengjiali@elecfans.com。快来联系小编吧!

**************************************************************************


往期回顾:

【高手问答】第13期——向资深PCB设计师取经:如何设计高速PCB

【高手问答】第12期—--韦东山老师VS嵌入式LINUX应用开发完全手册

【高手问答】第11期——与张飞老师一起成为硬件电路设计的expert

【高手问答】第10期—  宋雪松老师l手把手教你学51单片机

【高手问答】第9期——张工带你玩转STM32问答

【高手问答】第8期——社区之星李工为你的ARM问题解惑

【高手问答】第7期——与行工前辈一起畅谈DSP

【高手问答】第6期—— 李工解答PCB设计

【高手问答】第5期——STM32硬件问答

【高手问答】第4期——与社区之星王工聊聊labview设计

【高手问答】第3期——走进硬件电路设计

【高手问答】第2期——阿东带你走进fpga的逻辑编程设计

【高手问答】第1期——朱兆琪在线解答单片机C语言编程

这个肯定可以实现。具体如何实现,我没做过这方面的工程,但是我可以揣测着说说我的想法:
首先将歌词存储先存储起来,用AD采样声音,之后经过一定的算法,判断出何时唱,何时停止,唱是调用歌词,当然要对调用的歌词计数,这种方法对于快进和快退就不好处理,但是还是有办法的。
再就是直接语音识别,将语言转化成汉子,这个可以实现,但是难度太大,成本太高。
这个你可以参考一下网上流传的音乐频谱仪。

想用不同类型的变量,可以直接取不同的名字啊,为什么要用同一个名字呢?
可以采用赋值和强制转化的方式来搞定。
变量的类型,决定着内存的寻址方式,比如int是4位,double是8位,如果类型多变,那么怎么确定他的寻址方式,那个地方去辨别他到底是属于哪一类呢,机器很笨的,不可能根据你的意识来执行一些命令,如果想使用自定义类型,可以用共用体

共用体和结构体就是为解决需要具备多种类型的数据结构而生的。

一直和刘哥学习

刘老师您好@xymbmcu ,想问,C8051340中的ADC在启动之后即开始AD转换,但每次转换可有触发方式?例如有些单片机是可以靠定时器的每溢出一次就触发转换一次的,C8051F可以么?还是配置转换速率后,启动ADC之后就自己不停的转换了呢?

刘老师我是个爱音乐的孩纸,请问一下怎样可以让歌词随着音乐滚动播放呢?有没有这种可能?求@xymbmcu  ,12864液晶显示

请教一下,如果在keil和proteus没有找到相对应的单片机应该如何解决?我使用的是STC15F204EA。另外:(1)论坛积分怎样拿?(2)有没有一些比较便宜的ADC芯片介绍,要求是10位~16位的。(3)常用的IC(如功率管)应该到哪里选型?TI,AD那些官都太贵了。@xymbmcu  

最近做个网口转串口,用LM3S9B92芯片,但是烧录程序时候显示上电正常,但是连接不成功。jtag电路是正确的,在其它板子上验证过,麻烦刘老师帮忙分析下什么原因?多谢!@xymbmcu

关于TMOD的工作方式的问题:记得在使用定时器的时候 是TMOD=0x11;  但是为什么到了串口通信时初始化函数里的TMOD=0x20?,这样做有什么好处呢?拜托咯刘老师@xymbmcu

跟着刘老师学习很自在,不会因为问题简单就不帮忙分析解决,很热情,真心给赞

请教刘老师以下几个问题哈@xymbmcu
1,看到有人说这个总线协议与RS485通信协议有什么相同的?不同的?与CAN总线有什么区别?
2,它一条线上可挂64个设备,这条线是否就是220V的交流线?或是其他什么硬件连接?
3,KNX/EIB总线是否有专用的接口IC,类似M啊,MAX232或其他的CAN总线接口芯片?
4,是不是这个总线很牛B,在智能楼宇等强电控制领域行业很多使用?

之前一直使用变量声明是因为B.c需要调用A.c里定义的变量。
例如 :
在A.c中定义 unsigned char x= 0;
为了在B.c中使用x这个变量,我一般的做法是,在A.h中声明 extern unsigned char x;然后再B.c中 #include "A.h";当然也可以直接在B.c中直接声明extern unsigned char x;也可以达到目的。
现在问题来了,我希望x是volatile类型的,同时在某些文件里我又希望x是const类型的,那么我是不是可以在不同的文件中对x进行不同的声明呢?
例如:
在B.c中声明 extern volatile unsigned char x;在C.c中声明 extern const volatile unsigned char x;这样是否可以达到目的?
另外,在B.c中声明 extern volatile unsigned char x;是否意味着在B.c文件中,x是volatile类型的,而在B.c文件之外x是非volatile的(除非进行同样的声明)?
麻烦刘老师了@xymbmcu

这个完全可以人为控制。如:AD0EN = 1;意思是ADC开始工作,同理AD0EN = 0;就是停止了。
当然这里还需要注意一下这些标志位,原理与中断等是类似的。
AD0BUSY = 1;                         // 开始转换
while(!AD0INT);                // 等待转换完成
AD0INT = 0;                     // 清除中断标志

/************************************************************************************/
// 引用外部头文件
/************************************************************************************/
#include "ADC.h"
/************************************************************************************/
// 常量及全局变量定义
/************************************************************************************/
#define AIN1 0x04
#define AIN2 0x05
#define GND         0x1f
#define TEMP 0x1E
#define ADC_CLK 1600000
#define T_US 20
#define sysclk 48000000
/*************************************************************************************/
//
//                                                 ADC硬件驱动程序函数定义
//
/*************************************************************************************/
/***********************************************************************************
* Function: ADC_Init;
*
* Description: ADC初始化函数;
*              
* Input:  none;
*
* Output: none;
*
* Return: none;
*
* Note:   none;
************************************************************************************/
void ADC_Init (void)
{
        //REF0CN = 0x07;//使用ref电压基准
        AMX0P = TEMP;//选择TempSensor
        AMX0N = GND;//选择GND
        ADC0CF=(sysclk/ADC_CLK)<<3;//ADC转换时钟
        ADC0CN = 0x00;
}
/***********************************************************************************
* Function: ADC_Enable;
*
* Description: ADC使能函数, ADC开始工作;
*              
* Input:  none;
*
* Output: none;
*
* Return: none;
*
* Note:   none;
************************************************************************************/
void ADC_Enable(void)
{
        AD0EN = 1;
}
/***********************************************************************************
* Function: ADC_Disable;
*
* Description: ADC关闭函数, ADC停止工作;
*              
* Input:  none;
*
* Output: none;
*
* Return: none;
*
* Note:   none;
************************************************************************************/
void ADC_Disable(void)
{
        AD0EN = 0;
}
/***********************************************************************************
* Function: ADC_Read;
*
* Description: 读取ADC转换数据函数;
*              
* Input:  none;
*
* Output: *p, 通道1采样值; *(p+1),通道1采样值; *(p+2),温度通道采样值;
*
* Return: none;
*
* Note:   none;
************************************************************************************/
void ADC_Read(int *p)
{
        AD0INT = 0;     // 清除中断标志
               
                AMX0P = AIN1;        //改变AD通道
                Delay_us(T_US);
                AD0BUSY = 1;        //开始转换
            while(!AD0INT); // 等待转换完成
                AD0INT = 0;     // 清除中断标志
                *p++ = (unsigned int)ADC0H*256 + ADC0L; // 读取并计算AD值
                                
                AMX0P = AIN2;        //改变AD通道
                Delay_us(T_US);
                AD0BUSY = 1;        //开始转换
            while(!AD0INT); // 等待转换完成
                AD0INT = 0;     // 清除中断标志
                *p++ = (unsigned int)ADC0H*256 + ADC0L; // 读取并计算AD值
               
                AMX0P = TEMP;        //改变AD通道
                Delay_us(T_US);
                AD0BUSY = 1;        //开始转换
            while(!AD0INT); // 等待转换完成
                AD0INT = 0;     // 清除中断标志
                *p = (unsigned int)ADC0H*256 + ADC0L; // 读取并计算AD值
}
/***********************************************************************************
* Function: ADC_ISR;
*
* Description: 中断服务响应,完成ADC采样数据存储及通道切换;
*              
* Input:  none;
*
* Output: none;
*
* Return: none;
*
* Note:   none;
************************************************************************************/
void ADC_ISR (void) interrupt 10 using 3 //执行时间: 8uS
{

}
/***********************************************************************************/
// 文件结束
/***********************************************************************************/

我将的你的问题分为4个:
1.这些单片机都是51内核的,你就随便选择一个AT89C52的就行了,因为他们都是相同的。只是可能时间上有出入,你的实际测试。
2.积分的问题,请电子发烧友的美女主编们解答,我无权也不会。
3、4.便宜、价格是相对的,我不好推荐。建议你看看《通用集成电路速查手册》这方面的书,再对比他们的价格,找出既满足需要,也价格便宜的芯片。

对不起,LM3S9B92我没搞过,所以不会,不知论坛里哪位高手可以帮帮他了?

失之毫厘差之千里;再小的问题,乘以13亿就是一个大问题。
首先你的明白这些11、20是干嘛用的,他们是设置方式用的。
串口通信时,你用定时器1的方式0、1也行,但是这些都是需要人为装初值,这样势必会引入误差,随着次数的增多,误差越来越大,最后直接导致通信失败。
如果选自动重装(0x20),那么就会解决上面的问题。
这个我在《深入浅出玩转51单片机》一书中阐述的很清楚。

谢谢。

我看了半天,你4个问题中的“这个总线”指的是?
你的问题让我无从下手啊,呵呵。

是加了刘哥的qq群学习了嘛?

赢积分so easy!跟着表上面的来做哈!


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top