|  | 【程序】STM32F103C8T6最小系统板连接8位74HC595驱动的数码管模块并显示数字 | 
                
          |   一派掌門 二十級 |  | 
                
          |   一派掌門 二十級 | 
              【接线】PC13口接数码管模块的DIO端(数据端),图中为红线。该I/O口与板上自带的绿色S1 LED灯相连。
 PC14口接数码管模块的RCLK端(输出控制端),图中为橙线。
 PC15口接数码管模块的SCLK端(数据输入移位控制端),图中为黄线。
 深绿线为电源正极,电压为3.3V。
 褐线为电源负极。
 
 | 
|
        
                
          |   一派掌門 二十級 | 
              【程序】#include <stm32f10x.h>
 
 #define _BV(n) (1 << (n))
 
 uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
 
 void delay(void)
 {
 uint32_t i;
 for (i = 0; i < 20000; i++);
 }
 
 void SerIn(uint8_t data)
 {
 uint8_t i;
 for (i = 0; i < 8; i++)
 {
 GPIOC->BRR = _BV(15);
 if (data & 0x80)
 GPIOC->BSRR = _BV(13);
 else
 GPIOC->BRR = _BV(13);
 GPIOC->BSRR = _BV(15);
 data <<= 1;
 }
 }
 
 void ParOut(void)
 {
 GPIOC->BRR = _BV(14);
 GPIOC->BSRR = _BV(14);
 }
 
 int main(void)
 {
 uint8_t i = 0;
 
 // CNF=00: push-pull, MODE=11: 50MHz
 RCC->APB2ENR |= 0x10; // 开启PC时钟
 GPIOC->CRH = 0x33300000; // PC13~15设为输出
 
 while (1)
 {
 SerIn(seg8[i + 1]); // 要显示的数字
 SerIn(_BV(7 - i)); // 位选, _BV(0)为最右边
 ParOut();
 
 delay();
 i++;
 if (i > 7)
 i = 0;
 }
 }
 
 | 
|
        
                
          |   一派掌門 二十級 |  | 
|
        
                
          |   一派掌門 二十級 |  | 
|
        
                
          |   一派掌門 二十級 | 
              用JLink下载时,注意一定要选择Erase Full Chip(擦除整个芯片),并且要勾上Reset and Run(否则烧写后需要按复位键程序才能运行)。             | 
|
        
                
          |   一派掌門 二十級 | 
               Debug里面要选择J-LINK选项。             | 
|
        
                
          |   一派掌門 二十級 |  | 
|
        
                
          |   一派掌門 二十級 | 
              【0000~9999循环计数】#include <stm32f10x.h>
 
 #define _BV(n) (1 << (n))
 
 uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
 
 uint16_t num = 1970;
 
 void delay(void)
 {
 uint32_t i;
 for (i = 0; i < 20000; i++);
 }
 
 void SerIn(uint8_t data)
 {
 uint8_t i;
 for (i = 0; i < 8; i++)
 {
 GPIOC->BRR = _BV(15);
 if (data & 0x80)
 GPIOC->BSRR = _BV(13);
 else
 GPIOC->BRR = _BV(13);
 GPIOC->BSRR = _BV(15);
 data <<= 1;
 }
 }
 
 void ParOut(void)
 {
 GPIOC->BRR = _BV(14);
 GPIOC->BSRR = _BV(14);
 }
 
 int main(void)
 {
 uint8_t i = 0;
 
 // CNF=00: push-pull, MODE=11: 50MHz
 RCC->APB2ENR |= 0x10; // 开启PC时钟
 GPIOC->CRH = 0x33300000; // PC13~15设为输出
 
 while (1)
 {
 SerIn(seg8[num % 10000 / 1000]);
 SerIn(_BV(3));
 ParOut();
 delay();
 
 SerIn(seg8[num % 1000 / 100]);
 SerIn(_BV(2));
 ParOut();
 delay();
 
 SerIn(seg8[num % 100 / 10]);
 SerIn(_BV(1));
 ParOut();
 delay();
 
 SerIn(seg8[num % 10]);
 SerIn(_BV(0));
 ParOut();
 delay();
 
 i++;
 if (i > 100)
 {
 i = 0;
 num++;
 if (num >= 10000)
 num = 0;
 }
 }
 }
 
 | 
|
        
                
          |   一派掌門 二十級 | 
              【矩阵键盘显示数字,行PA0~3,列PA4~7】#include <stm32f10x.h>
 
 #define _BV(n) (1 << (n))
 
 uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
 
 uint8_t num = 0;
 
 void delay(void)
 {
 uint32_t i;
 for (i = 0; i < 20000; i++);
 }
 
 void SerIn(uint8_t data)
 {
 uint8_t i;
 for (i = 0; i < 8; i++)
 {
 GPIOC->BRR = _BV(15);
 if (data & 0x80)
 GPIOC->BSRR = _BV(13);
 else
 GPIOC->BRR = _BV(13);
 GPIOC->BSRR = _BV(15);
 data <<= 1;
 }
 }
 
 void ParOut(void)
 {
 GPIOC->BRR = _BV(14);
 GPIOC->BSRR = _BV(14);
 }
 
 void display(void)
 {
 SerIn(seg8[num % 100 / 10]);
 SerIn(_BV(1));
 ParOut();
 delay();
 
 SerIn(seg8[num % 10]);
 SerIn(_BV(0));
 ParOut();
 delay();
 }
 
 void keyscan(void)
 {
 uint8_t row, col, val;
 GPIOA->CRL = 0x22228888; // PA0~3设为带上下拉输入, PA4~7设为Push-Pull且速度为2MHz的输出
 GPIOA->ODR = 0x0f; // PA0~3设为上拉输入,并在PA4~7口输出低电平
 if ((GPIOA->IDR & 0x0f) != 0x0f) // 检查PA0~3是否有低电平输入,如果有则说明有按键按下,且按键出现在有低电平输入的那一行
 {
 display();
 if ((GPIOA->IDR & 0x0f) != 0x0f)
 {
 // 读行数
 row = ~GPIOA->IDR & 0x0f;
 if (row == 4)
 val = 8;
 else if (row == 8)
 val = 12;
 else
 val = (row - 1) * 4;
 
 // 线反转
 GPIOA->CRL = 0x88882222;
 GPIOA->ODR = 0xf0;
 display(); // ODR要等待一段时间才能成功改变输出
 
 // 读列数
 col = (~GPIOA->IDR >> 4) & 0x0f;
 if (col != 0)
 {
 if (col == 4)
 val += 3;
 else if (col == 8)
 val += 4;
 else if (col == 2)
 val += 2;
 else
 val++;
 num = val;
 }
 
 // 等待按键释放
 while ((GPIOA->IDR & 0xf0) != 0xf0)
 display();
 }
 }
 }
 
 int main(void)
 {
 // CNF=00: push-pull, MODE=11: 50MHz
 RCC->APB2ENR = 0x14; // 开启PA、PC时钟
 GPIOC->CRH = 0x33300000; // PC13~15设为输出
 
 while (1)
 {
 display();
 keyscan();
 }
 }
 
 | 
|