历史上的今天
今天是:2024年11月04日(星期一)
2021年11月04日 | 指针的第五大好处,指针在众多数组中的中转站作用
2021-11-04 来源:eefocus
一、使用proteus绘制简单的电路图,用于后续仿真

二、编写程序
/********************************************************************************************************************
---- @Project: Pointer
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200809
---- @ModifiedTime: 20200809
---- @Description:
---- 波特率是:9600 。
---- 通讯协议:EB 00 55 XX
---- 通过上位机来调用下位机对应的数组数据 。
---- 通过电脑串口调试助手,往单片机发送EB 00 55 XX 指令,其中EB 00 55是数据头,XX的取值范围是0x01 至 0x05,每个不同的值代表调用下位机不同的数组数据。0x01调用第1组数据,0x02调用第2组数据,0x05调用第5组数据。
---- 第1组:11 12 13 14 15
---- 第2组:21 22 23 24 25
---- 第3组:31 32 33 34 35
---- 第4组:41 42 43 44 45
---- 第5组:51 52 53 54 55
----
---- 下位机返回21个数据,前面5个是第1种不带指针函数返回的数据。中间5个是第2种不带指针函数返回的数据。最后5个是第3种带指针函数返回的数据。期间2组EE EE EE是各函数返回的数据分割线,为了方便观察,没实际意义。
---- 比如电脑发送:EB 00 55 02
---- 单片机就返回:21 22 23 24 25 EE EE EE 21 22 23 24 25 EE EE EE 21 22 23 24 25
---- 单片机:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————宏定义——————*/
#define FOSC 11059200L
#define BAUD 9600
#define T1MS (65536-FOSC/12/500) /*0.5ms timer calculation method in 12Tmode*/
#define const_array_size 5 /* 参与排序的数组大小 */
#define const_voice_short 19 /*蜂鸣器短叫的持续时间*/
#define const_rc_size 10 /*接收串口中断数据的缓冲区数组大小*/
#define const_receive_time 5 /*如果超过这个时间没有串口数据过来,就认为一串数据已经全部接收完,这个时间根据实际情况来调整大小*/
/*——————变量函数定义及声明——————*/
/*蜂鸣器的驱动IO口*/
sbit BEEP = P2^7;
/*LED*/
sbit LED = P3^5;
unsigned int uiSendCnt = 0; /*用来识别串口是否接收完一串数据的计时器*/
unsigned char ucSendLock = 1; /*串口服务程序的自锁变量,每次接收完一串数据只处理一次*/
unsigned int uiRcregTotal = 0; /*代表当前缓冲区已经接收了多少个数据*/
unsigned char ucRcregBuf[const_rc_size]; /*接收串口中断数据的缓冲区数组*/
unsigned int uiRcMoveIndex = 0; /*用来解析数据协议的中间变量*/
unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/
const unsigned char array_0x01[] = {0x11, 0x12, 0x13, 0x14, 0x15};
const unsigned char array_0x02[] = {0x21, 0x22, 0x23, 0x24, 0x25};
const unsigned char array_0x03[] = {0x31, 0x32, 0x33, 0x34, 0x35};
const unsigned char array_0x04[] = {0x41, 0x42, 0x43, 0x44, 0x45};
const unsigned char array_0x05[] = {0x51, 0x52, 0x53, 0x54, 0x55};
/**
* @brief 定时器0初始化函数
* @param 无
* @retval 初始化T0
**/
void Init_T0(void)
{
TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
}
/**
* @brief 串口初始化函数
* @param 无
* @retval 初始化T0
**/
void Init_USART(void)
{
SCON = 0x50;
TMOD = 0x21;
TH1=TL1=-(FOSC/12/32/BAUD);
}
/**
* @brief 外围初始化函数
* @param 无
* @retval 初始化外围
* 让数码管显示的内容转移到以下几个变量接口上,方便以后编写更上一层的窗口程序。
* 只要更改以下对应变量的内容,就可以显示你想显示的数字。
**/
void Init_Peripheral(void)
{
ET0 = 1;/*允许定时中断*/
TR0 = 1;/*启动定时中断*/
TR1 = 1;
ES = 1; /*允许串口中断*/
EA = 1;/*开总中断*/
}
/**
* @brief 初始化函数
* @param 无
* @retval 初始化单片机
**/
void Init(void)
{
LED = 0;
Init_T0();
Init_USART();
}
/**
* @brief 延时函数
* @param 无
* @retval 无
**/
void Delay_Long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i for(j=0;j<500;j++) /*内嵌循环的空指令数量*/ { ; /*一个分号相当于执行一条空语句*/ } } } /** * @brief 延时函数 * @param 无 * @retval 无 **/ void Delay_Short(unsigned int uiDelayShort) { unsigned int i; for(i=0;i ; /*一个分号相当于执行一条空语句*/ } } /** * @brief 串口发送函数 * @param unsigned char ucSendData * @retval 往上位机发送一个字节的函数 **/ void eusart_send(unsigned char ucSendData) { ES = 0; /* 关串口中断 */ TI = 0; /* 清零串口发送完成中断请求标志 */ SBUF = ucSendData; /* 发送一个字节 */ Delay_Short(400); /* 每个字节之间的延时,这里非常关键,也是最容易出错的地方。延时的大小请根据实际项目来调整 */ TI = 0; /* 清零串口发送完成中断请求标志 */ ES = 1; /* 允许串口中断 */ } /** * @brief 第1种函数 * @param ucArraySec * @retval * 第1种函数,内部不带指针,根据上位机相关的指令, * 直接返回对应的数组。由于不带指针,因此多用了5个for循环来搬运数组。 * 比较耗程序ROM容量,也不够简洁清晰。 **/ void send_array_1(unsigned char ucArraySec) { unsigned char i; switch (ucArraySec) { case 1: /* 直接返回第1个常量数组 */ for(i = 0; i < 5; i ++) { eusart_send(array_0x01[i]); } break; case 2: /* 直接返回第2个常量数组 */ for(i = 0; i < 5; i ++) { eusart_send(array_0x02[i]); } break; case 3: /* 直接返回第3个常量数组 */ for(i = 0; i < 5; i ++) { eusart_send(array_0x03[i]); } break; case 4: /* 直接返回第4个常量数组 */ for(i = 0; i < 5; i ++) { eusart_send(array_0x04[i]); } break; case 5: /* 直接返回第5个常量数组 */ for(i = 0; i < 5; i ++) { eusart_send(array_0x05[i]); } break; } } /** * @brief 第2种函数 * @param ucArraySec * @retval * 第2种函数,内部不带指针,根据上位机相关的指令, * 先转移对应的数组放到一个中间变量数组,然后发送数组。 * 由于不带指针,因此多用了6个for循环来搬运数组。 * 跟第1种函数一样,比较耗程序ROM容量,也不够简洁清晰。 **/ void send_array_2(unsigned char ucArraySec) { unsigned char i; unsigned char array_temp[5]; /* 临时中间数组 */ switch (ucArraySec) { case 1: /* 直接返回第1个常量数组 */ for(i = 0; i < 5; i ++) { array_temp[i] = array_0x01[i]; /* 先挨个把对应的数组数据转移到中间数组里 */ } break; case 2: /* 直接返回第2个常量数组 */ for(i = 0; i < 5; i ++) { array_temp[i] = array_0x02[i]; /* 先挨个把对应的数组数据转移到中间数组里 */ } break; case 3: /* 直接返回第3个常量数组 */ for(i = 0; i < 5; i ++) { array_temp[i] = array_0x03[i]; /* 先挨个把对应的数组数据转移到中间数组里 */ } break; case 4: /* 直接返回第4个常量数组 */ for(i = 0; i < 5; i ++) { array_temp[i] = array_0x04[i]; /* 先挨个把对应的数组数据转移到中间数组里 */ } break; case 5: /* 直接返回第5个常量数组 */ for(i = 0; i < 5; i ++) { array_temp[i] = array_0x05[i]; /* 先挨个把对应的数组数据转移到中间数组里 */ } break; } for(i = 0; i < 5; i ++) { eusart_send(array_temp[i]); /* 把临时存放在中间数组的数据全部发送出去 */ } } /** * @brief 第3种函数 * @param ucArraySec * @retval * 第3种函数,内部带指针,根据上位机相关的指令, * 先把对应的数组首地址传递给一个中间指针,然后再通过 * 指针把整个数组的数据发送出去,由于带指针,切换转移数组的数据非常快, * 只需传递一下首地址给指针就可以,非常高效,整个函数只用了1个for循环。 * 跟前面第1,2种函数相比,更加节省程序容量,处理速度更加快,更加简洁。 **/ void send_array_3(unsigned char ucArraySec) { unsigned char i; unsigned char *p_array; /* 临时中间指针,作为数组的中转站,非常高效 */ switch (ucArraySec) { case 1: /* 直接返回第1个常量数组 */ p_array = array_0x01; /* 把数组的首地址传递给指针,一个指令就可以,不用for来挨个搬移数据,高效 */ break; case 2: /* 直接返回第2个常量数组 */ p_array = array_0x02; /* 把数组的首地址传递给指针,一个指令就可以,不用for来挨个搬移数据,高效 */ break; case 3: /* 直接返回第3个常量数组 */ p_array = array_0x03; /* 把数组的首地址传递给指针,一个指令就可以,不用for来挨个搬移数据,高效 */ break; case 4: /* 直接返回第4个常量数组 */ p_array = array_0x04; /* 把数组的首地址传递给指针,一个指令就可以,不用for来挨个搬移数据,高效 */ break; case 5: /* 直接返回第5个常量数组 */ p_array = array_0x05; /* 把数组的首地址传递给指针,一个指令就可以,不用for来挨个搬移数据,高效 */ break;
史海拾趣
|
本公司提供良好发展机会和平台 我公司是一家主营一卡通智能管理系统、智能卡机具、热工仪表三大类产品,集研发、生产、销售、工程安装维护等全套工程实施,具有雄厚技术、销售实力的民营企业。 公司于2003年11月取得ISO9001认证;2005年8月,被杭 ...… 查看全部问答> |
|
详细信息: 书籍作者:天津市半导体器件厂 图书出版社:内发 图书类别:理科、工程技术 出版时间:1970-10 印刷时间:1970-10-01 开本:大16开 页数:135 页 装订:平装 & ...… 查看全部问答> |
|
急求助:有没有TTL电平直接转232和485两种电平的器件?有成品最好. 有没有TTL电平直接转232和485两种电平的器件?有成品最好. 也就是说用这个产品有三个接口.可以直接把TTL电平转成232和485信号输出.… 查看全部问答> |




