📄 ssi_rec_reg.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: ssi_rec_reg.c
** Last modified Date: 2008.01.18
** Last Version: v1.0
** Description: 通过 SSI 接口循环向外输出 0~F 的字模,74HC595 接收到 SSI 信号以后
** 在7段数码管上显示相应的字符。
** 同时,从74HC595接收回数据,并从独立的LED以16进制数显示
**
**------------------------------------------------------------------------------------------------------
** Created By: Kang qinhua
** Created date: 2008.01.18
** Version: v1.0
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#define HWREG(x) (*((volatile unsigned long *)(x)))
#define SYSCTL_PERIPH_SSI 0x10000010 // SSI 在系统控制器中的地址
#define SYSCTL_PERIPH_GPIOA 0x20000001 // GPIO A 在系统控制器中的地址
#define SYSCTL_PERIPH_GPIOB 0x20000002 // GPIO B 在系统控制器中的地址
#define SYSCTL_RCGC1 0x400fe104 // 运行模式时钟门控寄存器 1
#define SYSCTL_RCGC2 0x400fe108 // 运行模式时钟门控寄存器 2
#define SYSCTL_RCC 0x400fe060 // 运行-模式时钟配置寄存器
#define SYSCTL_PLLCFG 0x400fe064 // XTAL-PLL转换寄存器
#define SYSCTL_RCC_XTAL_MASK 0x000003C0 // Crystal attached to main osc
#define SYSCTL_RCC_OSCSRC_MASK 0x00000030 // 振荡器相关的位
#define SYSCTL_RCC_OSCSRC_MAIN 0x00000000 // 使用主振荡器
#define SYSCTL_RCC_OSCSRC_INT 0x00000010 // 使用内部振荡器
#define SYSCTL_RCC_OSCSRC_INT4 0x00000020 // 内部振荡器 / 4
#define SYSCTL_RCC_XTAL_SHIFT 6 // 移位到振荡器的相关位
#define SYSCTL_RCC_XTAL_3_57MHZ 0x00000100 // 使用3.579545MHz 晶振
#define SYSCTL_RCC_BYPASS 0x00000800 // PLL旁路
#define SYSCTL_RCC_USE_SYSDIV 0x00400000 // 使用系统时钟除数
#define SYSCTL_RCC_SYSDIV_MASK 0x07800000 // 系统时钟除数
#define SYSCTL_RCC_SYSDIV_SHIFT 23 // 移位到系统时钟除数的相关位
#define SYSCTL_PLLCFG_OD_MASK 0x0000C000 // 输出除数
#define SYSCTL_PLLCFG_OD_1 0x00000000 // OD值 1
#define SYSCTL_PLLCFG_OD_2 0x00004000 // 2
#define SYSCTL_PLLCFG_OD_4 0x00008000 // 4
#define SYSCTL_PLLCFG_F_MASK 0x00003FE0 // F输入值
#define SYSCTL_PLLCFG_R_MASK 0x0000001F // R输入值
#define SYSCTL_PLLCFG_F_SHIFT 5 // 移位到F的相关位
#define SYSCTL_PLLCFG_R_SHIFT 0 // 移位到R的相关位
#define SSI_BASE 0x40008000 // SSI 基地址
#define SSI_O_CR0 0x00000000 // SSI 控制寄存器0
#define SSI_O_CR1 0x00000004 // SSI 控制寄存器1
#define SSI_O_DR 0x00000008 // SSI 数据寄存器
#define SSI_O_SR 0x0000000C // SSI 状态寄存器
#define SSI_O_CPSR 0x00000010 // SSI 时钟分频寄存器
#define SSI_MODE_MASTER 0x00000000 // SSI 主模式
#define SSI_FRF_MOTO_MODE_0 0x00000000 // Moto 帧格式,极性0,相位0
#define SSI_CR0_FRF_MASK 0x00000030 // 帧格式屏蔽
#define SSI_CR1_SSE 0x00000002 // 同步端口使能
#define SSI_SR_TNF 0x00000002 // TX FIFO未满
#define SSI_SR_RNE 0x00000004 // RX FIFO 未满
#define GPIO_PORTA_BASE 0x40004000 // GPIO A 端口基地址
#define GPIO_PORTB_BASE 0x40005000 // GPIO B 端口基地址
#define GPIO_PIN_0 (1<<0) // GPIO 引脚 2
#define GPIO_PIN_1 (1<<1) // GPIO 引脚 3
#define GPIO_PIN_2 (1<<2) // GPIO 引脚 4
#define GPIO_PIN_3 (1<<3) // GPIO 引脚 5
#define GPIO_O_AFSEL 0x00000420 // 模式控制选择寄存器
#define GPIO_O_DIR 0x00000400 // GPIO 方向寄存器
#define GPIO_O_DATA 0x00000000 // GPIO 数据寄存器
#define BitRate 115200 // 设定波特率
#define DataWidth 8 // 设定数据宽度
// 此表为7段数码管显示0~F的字模
unsigned char DISP_TAB[16] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
const unsigned long g_pulXtals[] =
{
3579545,
3686400,
4000000,
4096000,
4915200,
5000000,
5120000,
6000000,
6144000,
7372800,
8000000,
8192000
};
//-----------------------------------------------------------------------------
// 函数原形:void delay(unsigned long d)
// 功能描述:延时数量为 d 个指令周期。
// 参数说明:unsigned long d,将要延时的时间数。
// 返回值:无
//-----------------------------------------------------------------------------
void delay(unsigned long d)
{
for(;d;d--);
}
//
//-----------------------------------------------------------------------------
// 函数原形:unsigned long SysCtlClockGet(void)
// 功能描述:获取处理器时钟速率。
// 参数说明:无。
// 返回值:时钟速率
//-----------------------------------------------------------------------------
unsigned long SysCtlClockGet(void)
{
unsigned long ulRCC, ulPLL, ulClk;
// 读 RCC.
ulRCC = HWREG(SYSCTL_RCC);
// 获取基本时钟速率
switch(ulRCC & SYSCTL_RCC_OSCSRC_MASK)
{
// 主时钟模式
case SYSCTL_RCC_OSCSRC_MAIN:
{
ulClk = g_pulXtals[((ulRCC & SYSCTL_RCC_XTAL_MASK) >>
SYSCTL_RCC_XTAL_SHIFT) -
(SYSCTL_RCC_XTAL_3_57MHZ >>
SYSCTL_RCC_XTAL_SHIFT)];
break;
}
// 内部时钟
case SYSCTL_RCC_OSCSRC_INT:
{
ulClk = 15000000;
break;
}
// 内部时钟的/4
case SYSCTL_RCC_OSCSRC_INT4:
{
ulClk = 15000000 / 4;
break;
}
default:
{
return(0);
}
}
// 使用PLL倍频的情况
if(!(ulRCC & SYSCTL_RCC_BYPASS))
{
// 获取PLL的配置值
ulPLL = HWREG(SYSCTL_PLLCFG);
ulClk = ((ulClk * (((ulPLL & SYSCTL_PLLCFG_F_MASK) >>
SYSCTL_PLLCFG_F_SHIFT) + 2)) /
(((ulPLL & SYSCTL_PLLCFG_R_MASK) >>
SYSCTL_PLLCFG_R_SHIFT) + 2));
// 2分频
if(ulPLL & SYSCTL_PLLCFG_OD_2)
{
ulClk /= 2;
}
// 4分频
if(ulPLL & SYSCTL_PLLCFG_OD_4)
{
ulClk /= 4;
}
}
if(ulRCC & SYSCTL_RCC_USE_SYSDIV)
{
// 调整时钟
ulClk /= ((ulRCC & SYSCTL_RCC_SYSDIV_MASK) >>
SYSCTL_RCC_SYSDIV_SHIFT) + 1;
}
return(ulClk);
}
//-----------------------------------------------------------------------------
// 函数原形:int main(void)
// 功能描述:主函数
// 参数说明:无
// 返回值:0
//-----------------------------------------------------------------------------
int main(void)
{
// 设置 SSI 时钟预分频器。
unsigned long ulMaxBitRate;
unsigned long ulPreDiv;
unsigned long ulSCR;
unsigned long ulClock;
unsigned char i=0,j;
unsigned long rec[17]; // 定义数据接收数组
// 使能 SSI
HWREG(SYSCTL_RCGC1) |= SYSCTL_PERIPH_SSI & 0x0fffffff;
// 使能 GPIO A 和 B口
HWREG(SYSCTL_RCGC2) |= ( SYSCTL_PERIPH_GPIOA | SYSCTL_PERIPH_GPIOB ) & 0x0fffffff;
delay(6);
// 配置 SSI 为主模式
HWREG(SSI_BASE + SSI_O_CR1) = 0;
ulClock = SysCtlClockGet();
ulMaxBitRate = ulClock / BitRate;
ulPreDiv = 0;
do
{
ulPreDiv += 2;
ulSCR = (ulMaxBitRate / ulPreDiv) - 1;
}
while(ulSCR > 255);
HWREG(SSI_BASE + SSI_O_CPSR) = ulPreDiv;
// 设置 SSI 传输协议和时钟速率。
HWREG(SSI_BASE + SSI_O_CR0) = ((ulSCR << 8) | (SSI_FRF_MOTO_MODE_0 << 6) |
(SSI_FRF_MOTO_MODE_0 & SSI_CR0_FRF_MASK) | (DataWidth - 1));
// 使能 SSI
HWREG(SSI_BASE + SSI_O_CR1) |= SSI_CR1_SSE;
// 设定 GPIO A 2~5 引脚为使用外设功能
HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
// 设置GPIO B 2~5引脚为输出口,输出到LED1~LED4
HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) |= (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) &= ~(GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
while (1)
{
// 循环输出 0~F 的字模
for (i=0; i<16; i++)
{
// 等待直到有空间。
while (!(HWREG(SSI_BASE + SSI_O_SR) & SSI_SR_TNF))
{
}
// 向SSI写数据。
HWREG(SSI_BASE + SSI_O_DR) = DISP_TAB[i];
delay(600000);
// while(HWREG(SSI_BASE + SSI_O_SR) & SSI_SR_RNE) ;
rec[i] = HWREG(SSI_BASE + SSI_O_DR);
for(j=0; j<16; j++)
{
if(DISP_TAB[j]==rec[i])
{
HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ((GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
GPIO_PIN_3) << 2))) = ~j; //用独立的LED输出相应的16进制
break;
}
}
// 输出后延时一段时间
delay(600000);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -