篇幅所限,这里只列部分代码,用得是STM32F0 DISCOVERY小板
初始化:
/* RCC configuration */
RCC_Config(); // 这里用的默认设置,没有外接晶振
/* GPIO configuration */
GPIO_Config();
/* SPI configuration */
SPI_Config();
/* DMA configuration */
DMA_Config();
/* NVIC configuration */
NVIC_Config();
/* Lcd initialize */
LCD_Init();
/* Lcd clear */
LCD_Clear();
各部分初始化:
void RCC_Config(void)
{
RCC_ClocksTypeDef RCC_Clocks;
/* SysTick end of count event each 1ms */
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
/* Enable APB1 bus clock */
RCC_APB1PeriphClockCmd(SPI2_CLK, ENABLE);
/* Enable AHB bus clock */
RCC_AHBPeriphClockCmd(DMA1_CLK |
SPI2_GPIO_CLK |
LCD_GPIO_CLK, ENABLE);
// /* Enable SPI2 peripheral GPIO port clocks */
// RCC_AHBPeriphClockCmd(SPI2_GPIO_CLK, ENABLE);
// /* Enable nokia5110 control GPIO port clocks */
// RCC_AHBPeriphClockCmd(LCD_GPIO_CLK, ENABLE);
}
/**
* @brief GPIO configuration.
* @param None
* @retval None
*/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
/* Connect GPIO pins for SPI2 as alternate function */
GPIO_PinAFConfig(SPI2_GPIO_PORT, SPI2_SCK_SOURCE, SPI2_SCK_AF);
GPIO_PinAFConfig(SPI2_GPIO_PORT, SPI2_MOSI_SOURCE, SPI2_MOSI_AF);
/* SPI SCK and MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = SPI2_SCK_PIN | SPI2_MOSI_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI2_GPIO_PORT, &GPIO_InitStructure);
/* Nokia5110 control pin configuration */
GPIO_InitStructure.GPIO_Pin = LCD_GPIO_DC |
LCD_GPIO_CE |
LCD_GPIO_RST |
LCD_GPIO_BL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LCD_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief SPI configuration. See the notes in detail
* @param None
* @retval None
*/
void SPI_Config(void)
{
SPI_InitTypeDef SPI_InitStructure;
// Set up the SPI peripheral
SPI_I2S_DeInit(SPI2);
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_Init(SPI2, &SPI_InitStructure);
// SPI_NSSInternalSoftwareConfig(SPI2, SPI_NSSInternalSoft_Set);
// Enable the SPI port
SPI_Cmd(SPI2, ENABLE);
}
/**
* @brief DMA configuration. See the notes in detail
* @param None
* @retval None
*/
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// Reset DMA configuration
DMA_StructInit(&DMA_InitStructure);
// 配置DMA控制器
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)lcd_buffer;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI2_DR_ADDRESS);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_PORT_TX_DMA_STREAM, &DMA_InitStructure);
// 使能DMA数据传输完成中断
DMA_ITConfig(SPI_PORT_TX_DMA_STREAM, DMA_IT_TC, ENABLE);
// CR2:TXDMAEN Tx缓冲DMA 使能。当此位被设置,TXE标志被设置时,产生一个DMA请求。
// 使能SPI DMA发送请求。
// 0: Tx 缓冲DMA禁止
// 1: Tx 缓冲DMA使能
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
// DMA_Cmd(SPI_PORT_TX_DMA_STREAM, ENABLE);
}
/**
* @brief NVIC configuration.
* @param None
* @retval None
*/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = SPI_PORT_DMA_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 向5110中写入一个字符串
void LCD_WriteString(uint8_t X, uint8_t Y, uint8_t *s)
{
// DMA_InitTypeDef DMA_InitStructure;
// uint8_t len = 0;
uint8_t *str = s;
int i = 0;
int lcd_index =0;
if(str == 0 )
{
return ;
}
// // Wait for the previous DMS request to end
// while(DMA_GetCurrDataCounter(SPI_PORT_TX_DMA_STREAM));
LCD_Set_XY(X,Y);
while(*str)
{
// Copy the display string to display buffer
for(i=0; i<6; i++)
{
lcd_buffer[lcd_index++] = font6x8[*str-32][i];
}
str++ ;
}
lcd_buffer[lcd_index++] = 0 ; // lcd_index ++ 多发送一个0否者最后一个字符会缺少一个像素
//#if 1
// Delay(1);
// DMA_InitStructure.DMA_BufferSize = lcd_index;
LCD_DC_DATA;
DMA_Cmd(SPI_PORT_TX_DMA_STREAM, DISABLE);
SPI_PORT_TX_DMA_STREAM->CNDTR = lcd_index;
// DMA_Init(SPI_PORT_TX_DMA_STREAM, &DMA_InitStructure);
DMA_Cmd(SPI_PORT_TX_DMA_STREAM, ENABLE);
// LCD_DC_DATA;
// SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
// Wait for the previous DMS request to end
// while(DMA_GetCurrDataCounter(SPI_PORT_TX_DMA_STREAM));
// SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
//
//#else
//LCD_DC_DATA();
// for(i=0 ;i<lcd_index ;i++)
// {
// LCD_Send(lcd_buffer[i], LCD_DATA);
// }
//#endif
}
中断服务程序
void SPI_PORT_DMA_TX_IRQHandler()
{
// DMA_ISR:TCIF5 传输完成标志
// 该位由硬件设置。由软件对DMA_IFCR 寄存器的相应位写1清除。
// 0: 在通道x上无传输完成 (TC) 的事件发生
// 1: 在通道x上发生了传输 (TC) 的事件
if (DMA_GetITStatus(DMA1_IT_TC5))
{
// DMA_IFCR:CTCIF5 传输完成标志清除,该位由软件置1清除。
// 0: 无效
// 1: 在DMA_ISR寄存器中清除相应的TCIF标志
DMA_ClearITPendingBit(DMA1_IT_TC5);
// // SPI_SR:TXE 发送缓冲区为空标志
// // 0: Tx 缓冲区非空
// // 1: TX 缓冲器空
// // 如果SPI2发送缓冲区非空,则在这里等待(中断服务函数里面做循环等待)!!!!
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) {
};
// // SPI_SR:BSY 忙标志
// // 0: SPI(或I2S)不忙
// // 1: (SPI 或I2S)通信忙或发送缓冲区不为空
// // 如果通信忙,则在这里等待(中断服务函数里面做循环等待)!!!!
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {
};
}
// GPIO_SetBits(GPIOC, nokiaSce); //SCE pin high
// STM_EVAL_LEDOff(LED4);
// // 关闭SPI DMA传输
DMA_Cmd(SPI_PORT_TX_DMA_STREAM, DISABLE);
}
中断可以进入,但是5110上什么也显示不出来。如果不用DMA,只用SPI,是可以显示的。请高手指导下。 |