使用SPI驱动数码管

代码:

7-seg.c

/*
  《AVR专题精选》随书例程
  
  3.通信接口使用技巧

  项目:改进的延时法实现半双工软件串口
  文件:7seg.c
  说明:SPI控制数码管驱动文件
        
  作者:邵子扬
  时间:2012年12月15日

*/

#include <avr/io.h>

extern unsigned char SPI_RW(unsigned char dat);

// LED 数码管数量
#define SEG_CNT   2

// 7 SEG LED, 共阳极字模(共阴极类似)
//
//     0
//    ---
//  5| 6 |1
//    ---
//  4|   |2
//    ---  .7
//     3
//
const unsigned char LEDMASK[] = 
{                        //7654 3210  No
  0xC0,  // 0              1100 0000  0
  0xF9,  // 1              1111 1001  1
  0xA4,  // 2              1001 0100  2
  0xB0,  // 3              1011 0000  3
  0x99,  // 4              1001 1001  4
  0x92,  // 5              1001 0010  5
  0x82,  // 6              1000 0010  6
  0xF8,  // 7              1111 1000  7
  0x80,  // 8              1000 0000  8
  0x90,  // 9              1001 0000  9
  0x88,  // A              1000 1000  10
  0x83,  // b              1000 0011  11
  0xC6,  // C              1100 0110  12
  0xA1,  // d              1010 0001  13
  0x86,  // E              1000 0110  14
  0x8E,  // F              1000 1110  15
  0xC2,  // G              1100 0010  16
  0x89,  // H              1000 1001  17
  0x7F,  // .              0111 1111  18
  0xF1,  // J              1111 0001  19
  0xFF,  // blank          1111 1111  20
  0xC7,  // L              1100 0111  21
  0xBF,  // -              1011 1111  22
  0xF7,  // _              1111 0111  23
  0xA3,  // o              1010 0011  24
  0xA7,  // [              1010 0111  25
  0xE3,  // u              1110 0011  26
  0xB3,  // ]              1011 0011  27
  0xAB,  // n              1010 1011  28
  0xFF,
  0xFF,
  0xFF
};

// 显示驱动文件
void DISP7SEG(unsigned char *ledbuf)
{
  unsigned char i, t;

  // Enable update
  PORTB |= (1 << PB2);

  for(i = 0; i < SEG_CNT; i++)
  {
    t = LEDMASK[ledbuf[i] % 32];
 
    // 缓存最高位控制数据闪烁
    if(ledbuf[i] & 0x80)
      t &= 0x7F;

    SPI_RW(t);
  }

  // Disable update
  PORTB &= ~(1 << PB2);
}

main.c

/*
  《AVR专题精选》随书例程
  
  3.通信接口使用技巧

  项目:SPI驱动数码管
  文件:main.c
  说明:主程序
        
  作者:邵子扬
  时间:2012年12月15日

*/

#include <avr/io.h>

// 系统时钟频率
#define F_CPU  1000000UL

#include <util/delay.h>

#include "macromcu.h"

// 定义SPI端口
#define CS    B, 2
#define SCK   B, 5
#define MOSI  B, 3


/*
  函数说明: SPI初始化
  输入参数:
  mode: b7:      1 slave, 0 master
        b65432:  not use
        b10:     mode  CPOL CPHA
                  3     1    1
                  2     1    0
                  1     0    1
                  0     0    0

  speed: b76543: not use
         b210:   speed   KHz
                   0     500   F/2
                   1     500   F/2
                   2     250   F/4
                   3     125   F/8
                   4     62.5  F/16
                   5     31.25 F/32
                   6     15.63 F/64
                   7     7.81  F/128
                   
*/
void SPI_init(char mode, char speed)
{
  unsigned char bSPR, bSPI2X, bMODE;

  PINDIR(CS,  PIN_OUTPUT);
  PINDIR(SCK, PIN_OUTPUT);
  PINDIR(MOSI,PIN_OUTPUT);

  // SPI mode
  switch(mode%4)
  {
    case 1:// mode 1
      bMODE = (0 << CPOL)|(1 << CPHA);
      break;
    case 2:// mode 2
      bMODE = (1 << CPOL)|(0 << CPHA);
      break;
    case 3:// mode 3
      bMODE = (1 << CPOL)|(1 << CPHA);
      break;
    default:// mode 0
      bMODE = (0 << CPOL)|(0 << CPHA);
      break;
  }

  // Master or Slave
  if((mode & 0x80) == 0)
    bMODE |= (1 << MSTR);

  // SPI speed
  bSPI2X = 0;
  switch(speed)
  {
    case 7:// F/128 = 7.8125K
      bSPR = (1 << SPR1)|(1 << SPR0);
      break;
    case 6:// F/64 = 15.625K
      bSPR = (1 << SPR1)|(0 << SPR0);
      break;
    case 5:// F/32 = 31.25K
      bSPR = (1 << SPR1)|(0 << SPR0);
      bSPI2X = 1;
      break;
    case 4:// F/16 = 62.5K
      bSPR = (0 << SPR1)|(1 << SPR0);
      break;
    case 3:// F/8 = 125K
      bSPR = (0 << SPR1)|(1 << SPR0);
      bSPI2X = 1;
      break;
    case 2:// F/4 = 250K
      bSPR = (0 << SPR1)|(0 << SPR0);
      break;
    default:// F/2 = 500K
      bSPR = (0 << SPR1)|(0 << SPR0);
      bSPI2X = 1;
      break;
  }
  SPCR = (1 << SPE)|bMODE|bSPR;
  SPSR = (bSPI2X << SPI2X);
}

// SPI读写
unsigned char SPI_RW(unsigned char dat)
{
  SPSR &= ~(1 << SPIF);
  SPDR = dat;
  while((SPSR & (1 << SPIF)) == 0);

  return SPDR;
}

// 系统初始化
void init()
{
  SPI_init(0, 0);
}

extern void DISP7SEG(unsigned char *ledbuf);

// LED显示缓存
unsigned char LEDBUF[2];
unsigned char cnt;

int main()
{

  init();  // 初始化

  for(;;)
  {
    _delay_ms(500);  // 延时500ms
    
    cnt++;           // 计数器递增

    LEDBUF[0] = cnt / 16; // 修改缓存内容
    LEDBUF[1] = (cnt % 16)|0x80;

    DISP7SEG(LEDBUF); // 更新显示
  }

  return 0;
}

仿真

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/734844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式】嵌入式Linux开发实战指南:从交叉编译到触摸屏交互

文章目录 前言&#xff1a;1.简介1.1. 交叉编译工具1.2. 项目开发流程&#xff1a;1.3. ARM开发板的连接方法 2. 开发板连接3. 系统文件 IO4. 设置共享文件夹3.1. 读文件3.2. 写文件3.2. 设置文件偏移量 4. LCD显示屏显示4.1. LCD 显示颜色4.2. 将文件下载到开发板4.2.1. 在CRT…

JDK动态代理

JDK动态代理源码分析 4.1 JDK动态代理的实现 需要动态代理的接口 /**需要动态代理的接口 */ public interface Movie {void player();void speak();需要动态代理的接口的真实实现 /**需要动态代理接口的真实实现 */ public class RealMovie implements Movie {Override publi…

win10 安装openssl并使用openssl创建自签名证书

win10创建自签名证书 下载安装配置openssl 下载地址&#xff1a; https://slproweb.com/download/Win64OpenSSL-3_3_1.exe https://slproweb.com/products/Win32OpenSSL.html 完成后安装&#xff0c;一路next&#xff0c;到达选位置的之后选择安装的位置&#xff0c;我这里选…

一文详解分布式 ID

分布式系统中&#xff0c;我们经常需要对数据、消息等进行唯一标识&#xff0c;这个唯一标识就是分布式 ID&#xff0c;那么我们如何设计它呢&#xff1f;本文将详细讲述分布式 ID 及其生成方案。 一、为什么需要分布式 ID 目前大部分的系统都已是分布式系统&#xff0c;所以在…

如何打造稳定、好用的 Android LayoutInspector?

速度极慢&#xff0c;遇到复杂的布局经常超时 某些情况无法选中指定的 View 本文将围绕 LayoutInspector 的痛点&#xff0c;分析问题并修复&#xff0c;最终将 LayoutInspector 变成一个稳定、好用的插件。 二、加速 Dump View Hierarchy 2.1 问题描述 开发复杂业务的同学…

【STM32-启动文件 startup_stm32f103xe.s】

STM32-启动文件 startup_stm32f103xe.s ■ STM32-启动文件■ STM32-启动文件主要做了以下工作&#xff1a;■ STM32-启动文件指令■ STM32-启动文件代码详解■ 栈空间的开辟■ 栈空间大小 Stack_Size■ .map 文件的详细介绍■ 打开map文件 ■ 堆空间■ PRESERVE8 和 THUMB 指令…

用Java获取键盘输入数的个十百位数

这段Java代码是一个简单的程序&#xff0c;用于接收用户输入的一个三位数&#xff0c;并将其分解为个位、十位和百位数字&#xff0c;然后分别打印出来。下面是代码的详细解释&#xff1a; 导入所需类库: import java.util.Scanner;&#xff1a;导入Scanner类&#xff0c;用于从…

使用Gradle查看Android项目中库的依赖关系

| | -- com.android.support:support-compat:25.3.1 | | | — com.android.support:support-annotations:25.3.1 | | -- com.android.support:support-media-compat:25.3.1 | | | -- com.android.support:support-annotations:25.3.1 | | | — com.android.support:support…

Windows10中端口被占用处理方法

前言 在Windows 10中&#xff0c;查看端口被占用情况的方法主要依赖于命令行工具netstat。以下是详细步骤&#xff0c;以及必要的解释和归纳&#xff1a; 打开命令提示符 方法1&#xff1a;使用快捷键Win R&#xff0c;打开“运行”对话框&#xff0c;输入cmd&#xff0c;然…

深入讲解C++基础知识(一)

目录 一、基本内置类型1. 类型的作用2. 分类3. 整型3.1 内存描述及查询3.2 布尔类型 —— bool3.3 字符类型 —— char3.4 其他整型 4. 有符号类型和无符号类型5. 浮点型6. 如何选择类型7. 类型转换7.1 自动类型转换7.2 强制类型转换7.3 类型转换总结 8. 类型溢出8.1 注意事项 …

5.XSS-反射型(post)利用:获取cookie

原理&#xff1a; 文件路径&#xff1a;\pikachu\pkxss\xcookie\post.html 将post.html文件&#xff0c;复制到皮卡丘的根路径下或者根下随意路径即可&#xff0c;并编辑文件 需要修改以下两个地址&#xff0c;第一个地址是将原界面的样子链接过来&#xff0c;让用户认为是原…

数据结构十三:2 - 3树和红黑树

一开始就接触这五点&#xff0c;会让人云里雾里&#xff0c;不利于了解这个数据结构。因为这种先给定义在推导的方式并不适合学习。它没有介绍红黑树的来源&#xff0c;而只是给你生硬的定义。 而学习红黑树的最好学习资料就是大名鼎鼎的《算法4》&#xff0c;如下&#xff1a…

微型操作系统内核源码详解系列五(四):cm3下svc启动任务

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…

LabVIEW电控旋翼测控系统

开发基于LabVIEW开发的电控旋翼测控系统&#xff0c;通过高效监控和控制提升旋翼系统的性能和安全性。系统集成了多种硬件设备&#xff0c;采用模块化设计&#xff0c;实现复杂的控制和数据处理功能&#xff0c;适用于现代航空航天领域。 项目背景 传统旋翼系统依赖机械和液压…

算法04 模拟算法之一维数组相关内容详解【C++实现】

大家好&#xff0c;我是bigbigli&#xff0c;模拟算法我们将分为几个章节来讲&#xff0c;今天我们只看一维数组相关的题目 目录 模拟的概念 训练&#xff1a;开关灯 解析 参考代码 训练&#xff1a;数组变化 解析 参考代码 训练&#xff1a;折叠游戏 解析 参考代码 …

vscode+picgo+gitee实现Markdown图床

vscode中编辑Markdown文件&#xff0c;复制的图片默认是保存在本地的。当文档上传csdn时&#xff0c;会提示图片无法识别 可以在gitee上创建图床仓库&#xff0c;使用picgo工具上传图片&#xff0c;在Markdown中插入gitee链接的方式来解决该问题。 一、 安装picgo工具 1.1 v…

IOS开发学习日记(十六)

目录 App间的唤起和通信 App跳转 通过Scheme唤起其他App Universal Link 组件化 App间的唤起和通信 App跳转 使用URL Scheme支持App启动、跳转及参数传递 分享 / 登陆 / 拉起App Store等 设置URL Type 在UIApplication中处理参数和业务逻辑 -(BOOL)application:(UIApp…

强化安全新篇章:韶关石油化工可燃气体报警器年检解析

韶关&#xff0c;这座位于广东省北部的城市&#xff0c;近年来在石油化工行业取得了显著的发展。 随着一批批大型石化企业的进驻和投产&#xff0c;韶关不仅成为了区域性的石化产业基地&#xff0c;也为地方经济带来了强劲的增长动力。 然而&#xff0c;随着石化产业的快速发…

Selenium WebDriver - 网络元素

本文翻译整理自&#xff1a;https://www.selenium.dev/documentation/webdriver/elements/ 文章目录 一、文件上传二、定位策略1、传统定位器2、创建定位器3、类名4、CSS选择器5、id6、NAME7、链接文本8、部分链接文本9、标签名称10、xpath11、相对定位器它是如何工作的可用相对…