我写了(IMO)几乎最简单的ARM应用程序,它没有工作:)什么可能是错的?错过了什么?
闪存写入和CPU复位后,寄存器中有垃圾.
请善待,如果你知道,请告诉我在STM32F1上运行最简单的应用程序需要做些什么.
也许是某人可以列举在申请开始前必须做的事情,即.
应用程序:
@Directives
.thumb @.code 16
.syntax unified
.section .text
.org 0 @ Alters location of pointer - in this case set to zero
vectors: @ Define basic vectors for specific capabilities
.word _start + 1 @ Set - start address and increment pointer
.word _nmi_handler + 1 @ Below all other vectors will be declared:
.word _hard_fault + 1
.word _memory_fault + 1
.word _bus_fault + 1
.word _usage_fault + 1
_start:
mov …Run Code Online (Sandbox Code Playgroud) 你们知道如何为I2C奴隶启用时钟延长吗?
将此函数I2C_StretchClockCmd(I2C2, ENABLE)放入I2C初始化是否足够?
时钟拉伸如何正常工作?
我尝试使用DMA通道使用SPI发送数据.当我在没有DMA的情况下发送一切都没问题,但是用DMA确实是错误的.当我调试我的程序时,SPI DR寄存器始终为0.我想使用dma循环模式一直发送我的数组.有我的代码GPIO INIT:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
Run Code Online (Sandbox Code Playgroud)
SPI INIT
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
Run Code Online (Sandbox Code Playgroud)
DMA INIT:
DMA_InitTypeDef dma;
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_PeripheralDataSize …Run Code Online (Sandbox Code Playgroud) 调试器可以在到达断点或用户暂停代码执行时停止在Cortex中执行代码。但是,当皮质停止在暂停状态下执行代码时,调试器是否冻结其他外围变量,如DMA,UART和TIMERS?
我在带有FreeRTOS的stm32L476上的RTC上有一个奇怪的行为。
它仅在RUN模式下第一次读取,RTC正在工作,因为从运行到运行,它保存了内部寄存器的值并且一直在上升。
另外,如果我在583行的stm32l4xx_hal_rtc.c处放置断点时进行调试,则:
tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);
*breakpoint* sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
Run Code Online (Sandbox Code Playgroud)
我可以看到tmpreg和TR寄存器如何更新,然后单击跳转到下一个断点时,显示的内容也相同。
那么,为什么在正常运行时它不起作用?
初始化代码(生成多维数据集MX):
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
/**Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initialize RTC and set the Time and Date
*/
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
sTime.Hours = 0; …Run Code Online (Sandbox Code Playgroud) 我正在使用STM32F4及其SPI与本教程中的74HC595进行通信。区别在于初学者,为简单起见,我使用非DMA版本。我使用STMCubeMX配置SPI和GPIO
问题是:我没有获得锁存器PIN,我将其设置为PA8以在传输期间足够快地切换。
我正在使用的代码:
spiTxBuf[0] = 0b00000010;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, spiTxBuf, 1, HAL_MAX_DELAY);
// while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(1);
Run Code Online (Sandbox Code Playgroud)
我尝试过的事情:
我如何才能更快地切换?我应该在SPI完成后创建并中断并在那里设置锁存器吗?
我有一个在 STM32f103C8 上运行的简单闪烁 LED 程序(没有初始化样板):
void soft_delay(void) {
for (volatile uint32_t i=0; i<2000000; ++i) { }
}
uint32_t iters = 0;
while (1)
{
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
soft_delay();
++iters;
}
Run Code Online (Sandbox Code Playgroud)
它是用Keil uVision v.5(默认编译器)和CLionusingarm-none-eabi-gcc编译器编译的。令人惊讶的是,arm-none-eabi-gcc 程序在发布模式 (-O2 -flto) 下运行速度慢 50%,在调试模式下运行速度慢 100%。
我怀疑有3个原因:
Keil过度优化(不太可能,因为代码很简单)
由于错误的编译器标志,arm-none-eabi-gcc 优化不足(我使用 CLion Embedded 插件`CMakeLists.txt)
初始化中的一个错误,导致芯片在使用arm-none-eabi-gcc时具有较低的时钟频率(待调查)
我还没有深入到优化和反汇编的丛林中,我希望有许多经验丰富的嵌入式开发人员已经遇到过这个问题并有答案。
更新1
通过尝试 Keil ArmCC 的不同优化级别,我了解了它如何影响生成的代码。它影响很大,尤其是执行时间。soft_delay()以下是每个优化级别的基准测试和函数反汇编(RAM 和 Flash 数量包括初始化代码)。
-O0:RAM:1032,闪存:1444,执行时间(20 次迭代):18.7 秒
soft_delay PROC
PUSH {r3,lr}
MOVS r0,#0
STR r0,[sp,#0]
B |L6.14|
|L6.8|
LDR r0,[sp,#0]
ADDS …Run Code Online (Sandbox Code Playgroud) 我需要将数据从PC发送到我的STM32F3,所以我决定使用uC中的内置USB。但现在我有一个问题 - 我想一次向 stm32 发送大量数据 - 我的意思是 200-500 字节之类的数据。
当我从 PC 发送少于 64 个图表的 minicom 数据包时 - 一切都很好 - 回调 CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) 发生一次 - 它启用 UsbRxFlag,只是为了通知正在运行的程序有可用数据。
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
if( (Buf[0] == 'A') & (Buf[1] == 'T') ){
GPIOB->BSRR = (uint32_t)RX_Led_Pin;
UsbRxFlag = 1;
}
return (USBD_OK);
/* USER CODE END 6 */
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试向 uC 发送更多数据(只是来自 minicom 的长文本)时,会发生一些奇怪的事情 - 有时 uC 根本没有反应 - 有时它不考虑某些数据。 …
我正在使用蓝色药丸,并试图找出中断。我有一个中断处理程序:
void __attribute__ ((interrupt ("TIM4_IRQHandler"))) myhandler()
{
puts("hi");
TIM4->EGR |= TIM_EGR_UG; // send an update even to reset timer and apply settings
TIM4->SR &= ~0x01; // clear UIF
TIM4->DIER |= 0x01; // UIE
}
Run Code Online (Sandbox Code Playgroud)
我设置了定时器:
RCC_APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC=7999;
TIM4->ARR=1000;
TIM4->EGR |= TIM_EGR_UG; // send an update even to reset timer and apply settings
TIM4->EGR |= (TIM_EGR_TG | TIM_EGR_UG);
TIM4->DIER |= 0x01; // UIE enable interrupt
TIM4->CR1 |= TIM_CR1_CEN;
Run Code Online (Sandbox Code Playgroud)
我的计时器似乎没有启动。但我认为我并没有真正启用它。我有没有??
我在很多示例代码命令中看到,例如:
NVIC_EnableIRQ(USART1_IRQn);
Run Code Online (Sandbox Code Playgroud)
NVIC_EnableIRQ() 到底发生了什么?
我用谷歌搜索过,但找不到与我的功能类似的实际裸机代码。
我似乎错过了关键的一步。
更新2020-09-23感谢本问题的回答者。技巧是在 NVIC_ISER 寄存器中设置中断号位。正如我在下面指出的,STM32F101xx …
我已经在STM32-F446re(Nucleo)上实现了USB CDC (VCP)。我正在使用int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)in 循环来接收数据。但是很多数据也被发送过来,因此我想要基于接收中断。
谁能帮我了解如何设置 USB CDC Rx 中断?