#include "stm32f10x_lib.h" //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#define HC595_nCS GPIO_Pin_0 //HC595_nCS = PA0
#define HC595_RCK GPIO_Pin_1 //HC595_RCK = PA1
#define SEG_A1 GPIO_Pin_8 //SEG_A1 = PC8
#define SEG_A2 GPIO_Pin_15 //SEG_A2 = PB15
#define SEG_A3 GPIO_Pin_9 //SEG_A3 = PC9
#define SEG_A4 GPIO_Pin_8 //SEG_A4 = PE8
u8 const NumberTube_TAB[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0~9
/*******************************************************************************
* Function Name : SEG_Init
* Description : SEG数码管引脚,SPI1引脚初始化
* Input : None
* Return : None
*******************************************************************************/
void SEG_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; // 声明一个IO口结构体变量
SPI_InitTypeDef SPI1_InitStructure; //声明一个SPI结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // 使能APB2外设GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); // 使能APB2外设GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); // 使能APB2外设GPIOC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE , ENABLE); // 使能APB2外设GPIOE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE); // 使能APB2外设SPI1时钟
//==========PA口IO结构体初始化============
GPIO_InitStructure.GPIO_Pin = HC595_nCS|HC595_RCK; //选择PA.0,PA.1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式为推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA寄存器
//==========PB口IO结构体初始化============
GPIO_InitStructure.GPIO_Pin = SEG_A2; //选择PB.15
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式为推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB寄存器
//==========PC口IO结构体初始化============
GPIO_InitStructure.GPIO_Pin = SEG_A1|SEG_A3; //选择PC.8,PC.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式为推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC寄存器
//==========PE口IO结构体初始化============
GPIO_InitStructure.GPIO_Pin = SEG_A4; //选择PE.8
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式为推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE寄存器
//==========SPI1复用功能初始化============
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //选择PA.4,PA.5, PA.6,PA.7
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //模式为复用推挽输出 (SPI1)
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA寄存器
//==========设置SPI1工作模式==============
SPI1_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向全双工
SPI1_InitStructure.SPI_Mode = SPI_Mode_Master; //设置为主SPI
SPI1_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
SPI1_InitStructure.SPI_CPOL = SPI_CPOL_High; //CPOL = 1
SPI1_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CPHA = 0
SPI1_InitStructure.SPI_NSS = SPI_NSS_Hard; //NSS由外部管脚管理
SPI1_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;//分频值为64
SPI1_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输LSB(低位)开始
SPI1_InitStructure.SPI_CRCPolynomial = 7;
SPI_I2S_DeInit(SPI1); //将外设SPI1寄存器重设为缺省值 ;
SPI_Init(SPI1, &SPI1_InitStructure);//初始化外设SPI1寄存器
//==========使能SPI1========================
SPI_Cmd(SPI1, ENABLE);//使能SPI1外设
GPIO_ResetBits(GPIOA, HC595_nCS);
}
/*******************************************************************************
* Function Name : SEG_BitSelect
* Description : 选择数码管的位选
* Input : data 选择码 ,data的取值为0x01,0x02,0x04,0x08
* Return : None
*******************************************************************************/
void SEG_BitSelect(u8 data)
{
if((data & 0x01) != 0) GPIO_ResetBits(GPIOC, SEG_A1); // 控制smgA1 = PC8
else GPIO_SetBits(GPIOC, SEG_A1);
if((data & 0x02) != 0) GPIO_ResetBits(GPIOB, SEG_A2); // 控制smgA2 = PB15
else GPIO_SetBits(GPIOB, SEG_A2);
if((data & 0x04) != 0) GPIO_ResetBits(GPIOC, SEG_A3); // 控制smgA3 = PC9
else GPIO_SetBits(GPIOC, SEG_A3);
if((data & 0x08) != 0) GPIO_ResetBits(GPIOE, SEG_A4); // 控制smgA4 = PE8
else GPIO_SetBits(GPIOE, SEG_A4);
}
/*******************************************************************************
* Function Name : SEG_Display
* Description : 数码管显示4位数据
* Input : data 需要显示的数据
* radix_point 小数点的位置,取值范围为4、3、2
* Return : None
*******************************************************************************/
void SEG_Display(u16 data,u8 radix_point)
{
u16 j,one,ten,hundred,thousand; //个,十,百,千,的变量声明
thousand = data / 1000; //计算千位
if(thousand != 0) data -= thousand*1000;
hundred = data / 100; //计算百位
if(hundred != 0) data -= hundred*100;
ten = data / 10; //计算十位
if(ten != 0) data -= ten*10;
one = data % 10; //计算个位
//-------------------显示千位数据----------------
GPIO_ResetBits(GPIOA, HC595_RCK);
if(radix_point==4) SPI_I2S_SendData(SPI1, NumberTube_TAB[thousand] & 0x7f);
else SPI_I2S_SendData(SPI1, NumberTube_TAB[thousand] );
GPIO_SetBits(GPIOA, HC595_RCK);
SEG_BitSelect(0x08); //打开数码管位选端
for(j=0;j<500;j++); //小段延时
SEG_BitSelect(0x00); //关闭显示
//-------------------显示百位数据----------------
GPIO_ResetBits(GPIOA, HC595_RCK);
if(radix_point==3) SPI_I2S_SendData(SPI1, NumberTube_TAB[hundred] & 0x7f);
else SPI_I2S_SendData(SPI1, NumberTube_TAB[hundred] );
GPIO_SetBits(GPIOA, HC595_RCK);
SEG_BitSelect(0x01);
for(j=0;j<500;j++);
SEG_BitSelect(0x00); //关闭显示
//-------------------显示十位数据----------------
GPIO_ResetBits(GPIOA, HC595_RCK);
if(radix_point==2) SPI_I2S_SendData(SPI1, NumberTube_TAB[ten] & 0x7f);
else SPI_I2S_SendData(SPI1, NumberTube_TAB[ten] );
GPIO_SetBits(GPIOA, HC595_RCK);
SEG_BitSelect(0x02);
for(j=0;j<500;j++);
SEG_BitSelect(0x00); //关闭显示
//-------------------显示个位数据----------------
GPIO_ResetBits(GPIOA, HC595_RCK);
SPI_I2S_SendData(SPI1, NumberTube_TAB[one] );
GPIO_SetBits(GPIOA, HC595_RCK);
SEG_BitSelect(0x04);
for(j=0;j<500;j++);
SEG_BitSelect(0x00); //关闭显示
}
/*******************************************************************************
* Function Name : SEG_POWEROFF
* Description : SEG数码管关闭
* Input : None
* Return : None
*******************************************************************************/
void SEG_POWEROFF(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , DISABLE); // 关闭APB2外设SPI1时钟
GPIO_SetBits(GPIOC, SEG_A1);
GPIO_SetBits(GPIOB, SEG_A2);
GPIO_SetBits(GPIOC, SEG_A3);
GPIO_SetBits(GPIOE, SEG_A4);
}
然后main.c文件如下:int main()
{
// u16 i=0,j;
#ifdef DEBUG
debug();
#endif
//RCC_Configuration();//使能外设时钟
SEG_Init();
//========实现数码管显示==========
while (1)
{
// for(i=1;i<9;i++)
// {
// for(j=0;j<500;j++)
// SEG_Display(i,3);
// }
SEG_Display(1234,2);
Delay_Ms(2000); Delay_Ms(2000);Delay_Ms(2000);
}
}
/*******************************************************************************
* Function Name : Delay_Ms
* Description : delay 1 ms.
* Input : time (ms)
* Output : None
* Return : None
*******************************************************************************/
void Delay_Ms(u16 time) //延时函数
{
u16 i,j;
for(i=0;i
for(j=1000;j>0;j--);
}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
//==========================使用外部RC晶振========================================
RCC_DeInit(); //初始化为缺省状态
RCC_HSEConfig(RCC_HSE_ON); //高速时钟使能
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待高速时钟使能就绪
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state
RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLCmd(ENABLE); // Enable PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source
}