第9期——张工带你玩转STM32问答
张工带你玩转STM32问答
高手问答第9期
小编导读:
一周一期的高手问答,又在周一与大家相见了。本期(8.25~8.31)的主题是与STM32相关的问答。我们请到了拥有丰富经验的张工。
简 介:
张工,论坛用户名:@指上谈兵123,毕业后一直从事嵌入式的开发工作,使用过pic,51,瑞萨,义隆等芯片开发,做过opencv方面的手册的。
假如你在纠结如何才能将STM32中的图片保存到SD
假如你还在为捕获时出现频率跳变出现问题
。 苦恼的话!
或许你可以在本帖下面,跟帖+并@指上谈兵123张工,说不定你的问题在下个楼层或是下一页的楼层会有一个指引方向给你,或者是问题被解决了。
Elecfans高手问答,根据主题,回帖提问,解答你的疑惑。
————————————————————————————————————————
社区高手招募
不限专业领域、不限技术方向,只要你是一个有活力并乐于分享的开发者,只要你愿意把自己的经验收获分享给大家,帮助众多从业者共同学习、共同进步,我们就欢迎你来做客社区高手问答。
联系方式:pengjiali@elecfans.com。快来联系小编吧!
————————————————————————————————————————
*************问答精华***************
往期回顾:
【高手问答】第8期——社区之星李工为你的ARM问题解惑
【高手问答】第7期——与行工前辈一起畅谈DSP
【高手问答】第6期—— 李工解答PCB设计
【高手问答】第5期——STM32硬件问答
【高手问答】第4期——与社区之星王工聊聊labview设计
【高手问答】第3期——走进硬件电路设计
【高手问答】第2期——阿东带你走进fpga的逻辑编程设计
【高手问答】第1期——朱兆琪在线解答单片机C语言编程
int main(void)
{
unsigned char i,data;
USART_InitTypeDef USART_InitStructure;
RCC_Configuration();
GPIO_Configuration();
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1,ENABLE);
data = 'A';
for(i=0; i<10; i++)
{
USART_SendData(USART1,data);
data++;
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
}
我明明循环了10次,却只打印出了9个数据,原本想输出“ABCDEFGHIJ”,但是实际输出出来的是“ACDEFGHIJ”
这是为什么呢?求大侠解惑
@指上谈兵123
笔记本虚拟2端口,然后keil下 输入 MODE COM4 115200,0,8,1 ASSING COM4<S2IN>S2OUT 提示*** error 76: command not supported 怎么解决@指上谈兵123
@指上谈兵123 大虾 端口配置锁定寄存器(GPIOx_LCKR)这个寄存器是具体怎么配置,看了半天数据手册没看懂。
1:端口配置锁键位被激活,下次系统复位前GPIOx_LCKR寄存器被锁住。 锁键的写入序列: 写1 -> 写0 -> 写1 -> 读0 -> 读1 最后一个读可省略,但可以用来确认锁键已被激活。 注:在操作锁键的写入序列时,不能改变LCK[15:0]的值。 操作锁键写入序列中的任何错误将不能激活锁键。
能给个代码示例么,这样更好理解
感激不尽
NVIC->IPR[10] &= ~(0xF<<0);
NVIC->IPR[10] |= (0xA<<4);
放了这么两句代码,出现错误,
USR\main.c(42): error: #136: struct "<unnamed>" has no field "IPR"
应该是缺少头文件吧,不知道需要什么头文件。我已经加了stm32f10x_nvic.h了,难道还要什么头文件?求助@指上谈兵123
找了很多例程,也反复看了数据手册,但还是有几个关键问题不太明白,求指教!
DAC_SetDualChannelData(DAC_Align_12b_L, 2047, 4095);
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);
DAC_SoftwareTriggerCmd(DAC_Channel_2,ENABLE);
printf("\r\n The Value is : %d ,%d\r\n",DAC_GetDataOutputValue(DAC_Channel_1),DAC_GetDataOutputValue(DAC_Channel_2));
我是这样配置的,串口输出The Value is :255,,127
不是很明白这代表的是什么?
2、而且数据手册上说取值范围为0~4095,输出值是最大Vref,但是我调程序时把值设置成5095串口仍然输出,且值变大,不太明,输白这是为什么?
3、我想使用DA转换的值,但是手册上也有说明,GPIO口设置成AIN模式输入模式怎么输出数据呢,还是要设置其他什么值?@指上谈兵123
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
把后面一句换成这个试试,亲!
你说的是程序下载吗,看看装了驱动没,还有串口号选对没,再就是tx/rx管脚插反没有,一般就是这些情况了
打开keil安装目录你会找到很多的例子的,比如我的安装目录是D:\Program Files\打开
D:\Program Files\keil\ARM\Examples\ST\STM32F10xFWLib\Examples\GPIO\IOToggle你会看到gpio的操作案例
例如下面代码
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : main.c
* Author : MCD Application Team
* Version : V2.0.1
* Date : 06/13/2008
* Description : Main program body.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "platform_config.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
ErrorStatus HSEStartUpStatus;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void Delay(vu32 nCount);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
debug();
#endif
/* System Clocks Configuration **********************************************/
RCC_Configuration();
/* NVIC Configuration *******************************************************/
NVIC_Configuration();
/* Configure all unused GPIO port pins in Analog Input mode (floating input
trigger OFF), this will reduce the power consumption and increase the device
immunity against EMI/EMC *************************************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_Init(GPIOE, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, DISABLE);
#ifdef USE_STM3210E_EVAL
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_Init(GPIOG, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, DISABLE);
#endif /* USE_STM3210E_EVAL */
/* Configure IO connected to LD1, LD2, LD3 and LD4 leds *********************/
/* Enable GPIO_LED clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_LED, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_LED, &GPIO_InitStructure);
while (1)
{
/* Turn on LD1 */
GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
/* Insert delay */
Delay(0xAFFFF);
/* Turn on LD2 and LD3 */
GPIO_SetBits(GPIO_LED, GPIO_Pin_7 | GPIO_Pin_8);
/* Turn off LD1 */
GPIO_ResetBits(GPIO_LED, GPIO_Pin_6);
/* Insert delay */
Delay(0xAFFFF);
/* Turn on LD4 */
GPIO_SetBits(GPIO_LED, GPIO_Pin_9);
/* Turn off LD2 and LD3 */
GPIO_ResetBits(GPIO_LED, GPIO_Pin_8 | GPIO_Pin_7);
/* Insert delay */
Delay(0xAFFFF);
/* Turn off LD4 */
GPIO_ResetBits(GPIO_LED, GPIO_Pin_9);
}
}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures Vector Table base location.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}
/*******************************************************************************
* Function Name : Delay
* Description : Inserts a delay time.
* Input : nCount: specifies the delay time length.
* Output : None
* Return : None
*******************************************************************************/
void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}
#ifdef DEBUG
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* Input : - file: pointer to the source file name
* - line: assert_param error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
你仔细查看一下吧,应该是缺少这个文件
挺好,继续学习,谢谢分享
3Q 3QQQQQQ
stm32的寄存器是 32位的 然而 操作也只能是以 32位的形式操作, 小弟想 单独对某一位操做 应该怎么做呢 就像8位的单片机一样可以写作PTA_PTA1=1(表示A口pin1置1). 用结构体联合体的方式应该怎么做呢? 或者还有什么其他的办法
笔记本虚拟2端口,然后keil下 输入 MODE COM4 115200,0,8,1 ASSING COM4<S2IN>S2OUT 提示*** error 76: command not supported 怎么解决
现在用的ST32+1963主要是点液晶屏TFT,现在点了一款分辯率是480*800的屏
屏用的IC是HX8369,点屏的时候要设置前后肩,在网上找了这些数组,下面这些值是怎么算出来的呢,
看了一下1963的规格书,就是B4与B6寄存器,但还是不知道怎么算出来的,请大侠们,大哥们指点一下
谢谢
#define LCD_HDP 799(只知道这个是屏的点阵)
#define LCD_HT 1000
#define LCD_HPS 51
#define LCD_LPS 3
#define LCD_HPW 8
#define LCD_VDP 479(只知道这个是屏的点阵)
#define LCD_VT 530
#define LCD_VPS 24
#define LCD_FPS 23
#define LCD_VPW 3
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; //尤其是对寄存器操作这句
return (0);
}
这段代码不是很懂 求大神解释!
怎么通过SPI 发送24位的数据比如发0xa00000,0xa04000,0xa08000,0xa0C000,0xa10000,0xa14000,0xa18000,0xa40000,0xa44000,等不能分开
就是SD_PowerON那个函数下,他写的发送完cmd0,然后发送cmd8/*---------------------cmd8------*/
SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND; //CMD8
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp7Error();
if (errorstatus == SD_OK)
{
CardType = SDIO_STD_CAPACITY_SD_CARD_V2_0;
SDType = SD_HIGH_CAPACITY;
}
else
{
SDIO_CmdInitStructure.SDIO_Argument = 0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_APP_CMD);
}
/*--------CMD55------------------------------------------------------------------------*/
SDIO_CmdInitStructure.SDIO_Argument = 0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SD_CMD_APP_CMD);
/***下面是循环发送CMD55+acmd41********************************************************/
求大神指点,cmd8发送之后如果返回不是SD_OK为什么要发送cmd55,返回正确也要发送CMD55,我看协议说CMD55是为了表征下一个命令是ACMD,但是循环开始后也发送CMD55+ACMD。这里的有什么用,求指点
求助@指上谈兵123 。
例如我在STM32上外接几个按键,实现以下功能:
按下按键1:发送数据1到串口;
按下按键2:发送数据2到串口。
预留几个按键接口。
现在我想通过上位机来实现程序的增加和删除功能,实现通过上位机删除按键x(如按键1、按键2)的功能,增加按键x的功能(按下按键x,发送数据x到串口)。请问应该怎么去实现?