作者共发了10篇帖子。 字体大小:较小 - 100% (默认)▼  内容转换:不转换▼
 
点击 回复
937 9
【程序】STM32F103C8T6最小系统板连接8位74HC595驱动的数码管模块并显示数字
一派护法 十九级
1楼 发表于:2016-11-21 22:50
一派护法 十九级
2楼 发表于:2016-11-21 22:55
【接线】
PC13口接数码管模块的DIO端(数据端),图中为红线。该I/O口与板上自带的绿色S1 LED灯相连。
PC14口接数码管模块的RCLK端(输出控制端),图中为橙线。
PC15口接数码管模块的SCLK端(数据输入移位控制端),图中为黄线。
深绿线为电源正极,电压为3.3V。
褐线为电源负极。
一派护法 十九级
3楼 发表于:2016-11-21 22:56
【程序】
#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;
    }
}
一派护法 十九级
4楼 发表于:2016-11-21 22:57
一派护法 十九级
5楼 发表于:2016-11-21 22:59
一派护法 十九级
6楼 发表于:2016-11-21 23:00
用JLink下载时,注意一定要选择Erase Full Chip(擦除整个芯片),并且要勾上Reset and Run(否则烧写后需要按复位键程序才能运行)。
一派护法 十九级
7楼 发表于:2016-11-21 23:01

Debug里面要选择J-LINK选项。
一派护法 十九级
8楼 发表于:2016-11-21 23:03
一派护法 十九级
9楼 发表于:2016-11-22 22:42
【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;
        }
    }
}
一派护法 十九级
10楼 发表于:2016-11-22 22:43
【矩阵键盘显示数字,行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();
    }
}

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:937 回复数:9
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2016-11-22 22:43
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。