一、新建工程
1、工程命名
2、選擇工程存儲位置
3、默認下一步
4、默認下一步
5、選擇沒有固件項目,下一步
二、器件放置并連線
1、點擊左邊工具欄中運放的形狀的符號
2、再點擊‘P’,搜索器件
3、搜索器件并放置連線
按鍵控制LED需要的器件有,按鍵、電容、LED、電阻、主控,主控選擇的是stm32f103r6。
4、器件連線,如下圖所示:
圖中使用了網絡標簽,網絡標簽是在電源、GND的那個工具欄中的DEFAULT。
三、網絡配置
1、想要仿真成功運行,首先配置主控參數,雙擊主控,選擇Program File,即代碼的hex文件路徑,以及Crystal Frequency,即晶振的頻率8M,具體如下圖所示:
2、仿真供電網絡的配置,點擊工具欄中的“design”,再點擊配置供電網絡(點擊design后的第四個選項),將"VDDA"增加到"VCC/VDD"中,將"VSSA"增加到"GND"中,如下圖所示:
四、代碼分享
1、LED代碼
#include "stm32f10x.h" // Device header/*** 函 數:LED初始化* 參 數:無* 返 回 值:無*/
void LED_Init(void)
{/*開啟時鐘*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7 ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //將PA1和PA2引腳初始化為推挽輸出/*設置GPIO初始化后的默認電平*/GPIO_SetBits(GPIOA, GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //設置PA1和PA2引腳為高電平
}/*** 函 數:LED1開啟* 參 數:無* 返 回 值:無*/
void LED1_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_1); //設置PA1引腳為低電平
}/*** 函 數:LED1關閉* 參 數:無* 返 回 值:無*/
void LED1_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_1); //設置PA1引腳為高電平
}/*** 函 數:LED1狀態翻轉* 參 數:無* 返 回 值:無*/
void LED1_Turn(void)
{if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0) //獲取輸出寄存器的狀態,如果當前引腳輸出低電平{GPIO_SetBits(GPIOA, GPIO_Pin_1); //則設置PA1引腳為高電平}else //否則,即當前引腳輸出高電平{GPIO_ResetBits(GPIOA, GPIO_Pin_1); //則設置PA1引腳為低電平}
}
2、按鍵代碼
#include "stm32f10x.h" // Device header
#include "Delay.h"/*** 函 數:按鍵初始化* 參 數:無* 返 回 值:無*/
void Key_Init(void)
{/*開啟時鐘*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //開啟GPIOB的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //將PB1和PB11引腳初始化為上拉輸入
}/*** 函 數:按鍵獲取鍵碼* 參 數:無* 返 回 值:按下按鍵的鍵碼值,范圍:0~2,返回0代表沒有按鍵按下* 注意事項:此函數是阻塞式操作,當按鍵按住不放時,函數會卡住,直到按鍵松手*/
uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0; //定義變量,默認鍵碼值為0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //讀PB1輸入寄存器的狀態,如果為0,則代表按鍵1按下{Delay_ms(20); //延時消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==0 ); //等待按鍵松手
// Delay_ms(20); //延時消抖KeyNum = 1; //置鍵碼為1}return KeyNum; //返回鍵碼值,如果沒有按鍵按下,所有if都不成立,則鍵碼為默認值0
}
3、main函數代碼
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"uint8_t KeyNum=0;
uint8_t flag=0;//流水燈方向
uint16_t LED_Value=0x0001;//GPIOA總共是16個IO口 ,二進制0000 0000 0000 0001,代表PA0為高電平,右邊是高位,左邊低位
int main(void)
{LED_Init();Key_Init();while (1){KeyNum=Key_GetNum();if(KeyNum==1)//按鍵切換流水燈的方向{if(flag==0) {flag=1;}else flag=0;}//當flag=0時,流水燈方向從A0-A7if(flag==0){// 輸出當前LED值GPIO_Write(GPIOA, ~LED_Value);//因為IO口為低電平時,燈才亮,于是給GPIOA的寄存器賦值的時候取反。// 延時// 左移一位,實現流水燈效果LED_Value <<= 1;// 如果左移后的值為0,表示已經移到最高位,重新從最低位開始if(LED_Value == 0x0100) {LED_Value = 0x0001;//0000 0000 0000 0001} }//當flag=1時,流水燈方向從A7-A0if(flag==1){// 輸出當前LED值GPIO_Write(GPIOA, ~LED_Value);//因為IO口為低電平時,燈才亮,于是給GPIOA的寄存器賦值的時候取反。// 延時// 右移一位,實現流水燈效果LED_Value >>= 1;// 如果左移后的值為0,表示已經移到最低位,重新從最高位PA7開始if(LED_Value == 0x0000) {LED_Value = 0x0080;//0000 0000 1000 0000} }Delay_s(100);}
}
main函數實現了按鍵控制流水燈的方向,定義了一個變量flag來控制流水燈的方向,按鍵按下可以對flag的值進行取反。LED的流水燈是通過GPIO的寄存器的值來左移右移實現流水燈的效果,具體看代碼注釋
五、仿真與實物不同之處
1、仿真的按鍵引腳需要外部電路上拉
2、仿真不需要晶振電路
3、仿真流水燈的延時不太準確,不知道是不是我電腦CPU仿真不行的原因。