Contents
- GPIO Write
- GPIO Read
- NVIC of GPIO
- General TIM (TIM 2-5)
- Accurate delay using TIM
- NVIC of TIM
- UART
- UART in swd
- UART with DMA
- UART with DMA in STM32H743
- USB device
- SD CARD
- fatfs
GPIO Write
cubeMX automatic generate initialization function of GPIo, then we use HAL_GPIO_WritePin
HAL_GPIO_WritePin(GPIOF,LED0_Pin,GPIO_PIN_SET);
GPIO Read
use HAL_GPIO_WritePin
GPIO_PinState pin_state = HAL_GPIO_ReadPin(GPIOE,KEY0_Pin);
NVIC of GPIO
set priority of NVIC in cubeMX, then write weak funcuion: HAL_GPIO_EXTI_Callback
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_3)
{
if(KEY1_SET == 0 ){
//...
}else{
//...
}
}
}
General TIM (TIM 2-5)
clock source of TIM2-5 is APB1, 84MHz
if we want to set TIM2 to 1Hz, then
APB1: | clock source | 84,000,000 |
PSC: | /(84-1) | 1,000,000 |
COUNTER: | /(1,000,000-1) | 1 |
Accurate delay using TIM
__HAL_TIM_SetCounter
__HAL_TIM_GetCounter
HAL_TIM_Base_Start
NVIC of TIM
config NVIC of TIM2 in cubemx, rewrite weak function, for example: HAL_TIM_PeriodElapsedCallback
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
//...
}
}
do not forget to use HAL_TIM_Base_Start_IT, which stats the NVIC
HAL_TIM_Base_Start_IT(&htim2);
UART
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
UART in swd
http://www.embedded-communication.com/en/misc/english-printf-using-st-link-debug-interface-swd-itm-view/
UART with DMA
###Transmit
HAL_UART_Transmit_DMA(&huart1,tx_buffer,BUFFER_SIZE);
###Receive
first enable uart idle interupt
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//idel
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_Receive_DMA(&huart2, UsartType2.RX_pData, BUFFER_SIZE);
define structure in main
#define BUFFER_SIZE 4096
typedef struct
{
uint8_t RX_flag:1; //IDLE receive flag
uint16_t RX_Size; //receive length
uint8_t RX_pData[BUFFER_SIZE]; //DMA receive buffer
}USART_RECEIVETYPE;
USART_RECEIVETYPE UsartType2;
then rewrite the USART1_IRQHandler
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint32_t temp;
if((__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2); // Clears the UART IDLE pending flag.
HAL_UART_DMAStop(&huart2); // Stops the DMA Transfer.
temp = huart2.hdmarx->Instance->NDTR; // Read DMA stream x number of data register
huart2.hdmarx->Instance->NDTR = 0; // Clear DMA stream x number of data register
int rx_len = BUFFER_SIZE - temp;
// Set RX_flag
UsartType2.RX_Size = BUFFER_SIZE - temp;
UsartType2.RX_flag=1; // Set RX_flag
HAL_UART_Receive_DMA(&huart2, UsartType2.RX_pData, BUFFER_SIZE); // start DMA interrupt and receives an amount of data in non blocking mode.
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
UART with DMA in STM32H743
注意在stm32h743 中,dma无法直接访问DTCMRAM中的内存,因此,需要将dma访问的变量定义在RAM_D2中,具体操作如下:
1. 修改ld文件
可以看ld文件中关于内存的分配:
MEMORY
{
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
}
在sections中添加下面定义:
.dma_buffer : /* Space before ':' is critical */
{
*(.dma_buffer)
} >RAM_D2
是添加dma_buffer定义,放入RAM_D2中。
2. 对dma访问的变量,添加定义__attribute__((section(“.dma_buffer”)))
uint8_t stringTest[1024] __attribute__((section(".dma_buffer"))); // 用于发送 32-align
typedef struct{
uint8_t RX_flag; //IDLE receive flag
uint16_t RX_Size; //receive length
}USART_RECEIVE_TYPE;
extern USART_RECEIVE_TYPE UsartType4 ;
extern uint8_t RX4_pData[BUFFER_SIZE];
Uuint8_t RX4_pData[BUFFER_SIZE] __attribute__((section(".dma_buffer"))) ;// 用于接收 32-align
3. 在发送与接收操作前,添加 SCB_CleanInvalidateDCache_by_Addr
接收代码如下:
if((__HAL_UART_GET_FLAG(&huart4,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(&huart4);// Clears the UART IDLE pending flag.
HAL_UART_DMAStop(&huart4);// Stops the DMA Transfer.
temp = ((DMA_Stream_TypeDef *)huart4.hdmarx->Instance)->NDTR;// Read DMA stream x number of data register
((DMA_Stream_TypeDef *)huart4.hdmarx->Instance)->NDTR = 0;
int rx_len = BUFFER_SIZE - temp;
// Set RX_flag
UsartType4.RX_Size = rx_len;
UsartType4.RX_flag=1; // Set RX_flag
char string[1024];
sprintf(string,"\n------\n%d\n------\n",rx_len);
HAL_UART_Transmit(&huart4,string,strlen(string),0xffff);
for (int i = 0; i < rx_len; ++i) {
HAL_UART_Transmit(&huart4,&RX4_pData[i],1,0xffff);
}
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)RX4_pData,BUFFER_SIZE+32); //重要
HAL_UART_Receive_DMA(&huart4, RX4_pData, BUFFER_SIZE); // start DMA interrupt and receives an amount of data in non blocking mode.
}
发送代码如下:
if(Uart4IsBusy==0){
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)stringTest,1024+32);
HAL_UART_Transmit_DMA(&huart4,stringTest, strlen(stringTest));
Uart4IsBusy = 1;
}
注意重写发送完成回调函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
if(huart->Instance == UART4){
Uart4IsBusy = 0;
}
}
USB device
modify the usbd_storage_if.c
#define STORAGE_LUN_NBR 1
#define STORAGE_BLK_NBR 100
#define STORAGE_BLK_SIZ 0x200
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
uint32_t n,i;
for(n = 0; n < blk_len; n++)
{
for(i = 0; i < STORAGE_BLK_SIZ; i++)
{
buf[n*STORAGE_BLK_SIZ+i] = msc_data[blk_addr+n][i];
}
}
return (USBD_OK);
/* USER CODE END 6 */
}
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 7 */
uint32_t n,i;
for(n = 0; n < blk_len; n++)
{
for(i = 0; i < STORAGE_BLK_SIZ; i++)
{
msc_data[blk_addr+n][i] = buf[n*STORAGE_BLK_SIZ+i];
}
}
return (USBD_OK);
/* USER CODE END 7 */
}
SD CARD
cubeMX
SDIO
DMA
NVIC
HAL_SD_CardInfoTypeDef SDCardInfo1;
HAL_SD_GetCardInfo(&hsd, &SDCardInfo1);
printf(" Warning: this program may erase all the TF card data. \r\n");
printf("\r\n Initialize SD card successfully!\r\n\r\n");
printf(" SD card information! \r\n");
printf(" BlockNbr : %d \r\n",SDCardInfo1.BlockNbr);
printf(" CardBlockSize : %d \r\n",SDCardInfo1.BlockSize);
printf(" RCA : %d \r\n",SDCardInfo1.RelCardAdd);
printf(" CardType : %d \r\n",SDCardInfo1.CardType);
uint8_t Buffer_Tx[512];
uint8_t Buffer_Rx[512];
HAL_StatusTypeDef Status;
int i = 0;
memset(Buffer_Tx,0x15,sizeof(Buffer_Tx));
/*------------------- Block Write --------------------------*/
if(HAL_SD_WriteBlocks_DMA(&hsd, Buffer_Tx, 0, 1) == HAL_OK)
{
printf("\r\n Write block successfully! %d\r\n",sizeof(Buffer_Tx));
for(i=0;i<sizeof(Buffer_Tx);i++)
{
printf("%d:0x%08x ",i,Buffer_Tx[i]);
}
printf("\r\n");
}
else
{
printf("\r\n Write block fail!\r\n");
}
/*------------------- Block Read --------------------------*/
if(HAL_SD_ReadBlocks_DMA(&hsd, Buffer_Rx, 0, 1) == HAL_OK)
{
printf("\r\n Read block successfully! %d\r\n",sizeof(Buffer_Rx));
for(i=0;i<sizeof(Buffer_Rx);i++)
{
printf("%d:0x%08x ",i,Buffer_Rx[i]);
}
printf("\r\n");
}
else
{
printf("\r\n Read block fail!\r\n");
}
fatfs
ref: https://zhuanlan.zhihu.com/p/27594211
first config sdio
config fats
FATFS fs; // fatfs
FIL fnew; // file
FRESULT res_flash; // result
UINT fnum; // size
BYTE ReadBuffer[1024] = {0}; // buffer
BYTE WriteBuffer[5] = "12345"; // buffer
uint8_t work[2048];
res_flash = f_mount(&fs, "", 1); //
if(res_flash == FR_NO_FILESYSTEM) //
{
printf("no file system, begin to format...\r\n");
res_flash = f_mkfs("", FM_FAT32, 0, work, sizeof work);
if(res_flash == FR_OK)
{
printf("format success\r\n");
res_flash = f_mount(NULL, "", 1);
res_flash = f_mount(&fs, "", 1);
}
else
{
printf("format fail\r\n");
}
}
else if(res_flash != FR_OK)
{
printf("FatFS mount fail(%d)\r\n", res_flash);
while(1);
}
else
{
printf("FatFS mount success\r\n");
}
res_flash = f_open(&fnew, "FatFS.txt", FA_CREATE_ALWAYS | FA_WRITE);
if(res_flash == FR_OK)
{
printf("open file success\r\n\r\n");
res_flash = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
res_flash = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
res_flash = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum);
}
else
{
printf("open file fail !!!%d \r\n",res_flash);
}
f_close(&fnew);
res_flash = f_open(&fnew, "FatFS.txt", FA_OPEN_EXISTING | FA_READ);
if(res_flash == FR_OK)
{
printf("open file success\\r\n\r\n");
res_flash = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
if(res_flash == FR_OK)
{
printf(" file size: %d\n", fnum);
printf(" data: %s\r\n\r\n\r\n", ReadBuffer);
}
else
{
printf("fail to readd data:(%d)", res_flash);
}
}
else
{
printf("fail to open file\r\n");
}
f_close(&fnew);