历史上的今天
今天是:2025年08月11日(星期一)
2021年08月11日 | STM32 | 请写一个函数输出如下波形
2021-08-11 来源:eefocus
前两天群友岸与桥在群里问了这样一个面试题:

看到这样一个问题,群里讨论得很热闹,几位群友也给出了一些解答,主要有两种思路:
① 第一种思路是:依次输出相应电平,高、低电平持续的时间根据题目要求确定即可。关键代码如下(代码来自昵称为宋阳的群友):
static void plus(uint16_t h_times, uint16_t l_times)
{
IO_HIGH();
HAL_Delay(h_times);
IO_LOW();
HAL_Delay(l_times);
}
static void outplus(void)
{
plus(2, 1);
plus(1, 2);
plus(3, 1);
plus(1, 1);
plus(2, 1);
plus(2, 1);
plus(3, 0);
}
实际测试结果如下:

② 第二种思路是:可以把这个波形看做数据(0x1A75B7)来看待,这样一来就可以通过一个GPIO来按照这个数据输出相应的高低电平就可以得到对应的波形。关键代码如下(代码来自@_GWD、上海-zak、习道道等群友):
uint32_t out_data = 0x1A75B7;
static void WaveOutput(uint32_t data)
{
int i;
for (i = 0; i < 21; i++)
{
if (data & 0x100000)
{
IO_HIGH();
}
else
{
IO_LOW();
}
data <<= 1;
HAL_Delay(1);
}
}
经过实测得到的波形与上面的方法得到的波形是一致的,都能满足题目的要求。
针对这个题目,似乎按照第一种方法能更快地做出来。但是,我觉得这道题目真正要考察的应该是第二种思路,因为这个思路就是软件I2C、SPI的套路呀,想要考察我们会不会使用GPIO模拟一些总线协议。
软件I2C的发送函数(代码来自:安富莱):
/*
*********************************************************************************************************
* 函 数 名: i2c_SendByte
* 功能说明: CPU向I2C总线设备发送8bit数据
* 形 参: _ucByte : 等待发送的字节
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{
uint8_t i;
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
I2C_SDA_1();
}
else
{
I2C_SDA_0();
}
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
if (i == 7)
{
I2C_SDA_1(); // 释放总线
}
_ucByte <<= 1; /* 左移一个bit */
i2c_Delay();
}
}
软件SPI的发送函数(代码来自:安富莱):
/*
*********************************************************************************************************
* 函 数 名: bsp_spiWrite0
* 功能说明: 向SPI总线发送一个字节。SCK上升沿采集数据, SCK空闲时为低电平。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_spiWrite0(uint8_t _ucByte)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
MOSI_1();
}
else
{
MOSI_0();
}
bsp_spiDelay();
SCK_1();
_ucByte <<= 1;
bsp_spiDelay();
SCK_0();
}
bsp_spiDelay();
}
看看,是不是一样的套路。SPI、I2C是两块重中之重的知识,而且也是我们嵌入式笔试面试中的高频考点,需要我们反复去理解,吸收。
史海拾趣
|
步进电机是一种完全数字化的电动执行机构,从原理上说,其角位移与驱动脉冲的个数成正比,在正常情况下,步进电机具有使用简单、运动精确、连续运行无累积误差等特点,因而被广泛应用于各种位置控制系统中。当前由于仪器内部的机械系统日益复杂,其 ...… 查看全部问答> |
|
/************************************************* *原型:void write_lcdbit(unsigned char bit) *功能:LCD送数 &nb ...… 查看全部问答> |
|
目前我的使用方法为: 配置过程: void Wdg_Init(void) { // Enable WDG clocks RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG , ENABLE); // PCKL1: 36MHZ // WWDG clock counter = (PCLK1/4096)/8 = 488 Hz (~2 ms) ...… 查看全部问答> |
|
使用的是友善之臂的mini2440, 在用activesync下载程序的时候不能下载,提示:A Corrupted file might be left on the device.是怎么回事呢? 原先都正常下载的。 这种问题持续好久,什么都没有修改,又可以下载了,很是奇怪。不知是 ...… 查看全部问答> |
|
NMAKE : fatal error U1073: don\'t know how to make \'D:\\WINCE500\\public\\common\\oak\\lib\\ARMV4I\\retail\\tchmain.lib\' Stop. NMAKE : fatal error U1077: \'D:\\WINCE500\\sdk\\bin\\i386\\nmake.exe\' : return code \'0x2\' Stop. ...… 查看全部问答> |
|
我最近在研究内核的启动过程,正在看代码,请问一下,镜像是在什么时候被拷贝到内存中的啊?怎么没有发现类似的代码? 我看到MAINSTONEIII 的bootloader代码里OALStartup.s中有copy bootloader image to RAM的代码,我觉得内核也应该会有类似的代 ...… 查看全部问答> |
|
急求!!请各位大虾帮我看看MSP430FE425的串口通讯程序有什么问题? 用MSP430FE425做485串口通讯,程序不知道那有问题,串口接收中断都进不了,各位大虾帮我看看我的程序有什么问题,急啊!!!!! void main (void) { init_usart(); while (1) { _BIS_SR (LPM0_bits); //低功耗模式0 i ...… 查看全部问答> |
|
一. 添加Altera库 1. 在Modelsim的安装目录下新建一个文件夹..\\Modelsim\\altera(大多数教程都这么安排,我也就这么做了,其实在任意目录都可以)。 2. 启动ModelsimSE,更改工作目录。File--->Change Directory。 3. 新建一个库。File--- ...… 查看全部问答> |
|
[hanker M4开发板试用]我的助手,我的虚拟串口 ——stellaris USB CDC应用 最后的试用期限就要到了。这两天也抓紧调试了USB库函数。在eeworld论坛上,小川 版主的帖子陪我走过这一周。现在将本周调试的虚拟串口程序与网友们分享。 摘要 本文首先简要介绍了Stellaris USB库的基本使用,在USB库函数下编写了虚拟串口程 ...… 查看全部问答> |




