搜索
bottom↓
回复: 1

菜鸟捣乱为何不用avr的spi直接驱动max7219?

[复制链接]

出0入0汤圆

发表于 2008-5-5 10:53:55 | 显示全部楼层 |阅读模式
您好:
我用的是mega16想要驱动max7219,可是查了很多例子都是用模拟spi口进行的,我用模拟时也好用,可是若用mega16自带的spi口确是不行,而我也没查到用avr自带spi直接驱动7219的例子,本站的很多代码都是模拟spi的,请问avr驱动7219是不是有别的说法?我的程序如下,但是有点乱,主要是做实验写了很多子函数。 特来求教,弄不明白四不甘心啊。
若谁做过,给个程序看啊。感激不尽了。
//ICC-AVR application builder : 2008-3-17 上午 10:49:32
// Target : M16
// Crystal: 3.6864Mhz
// Copyright (C), 1988-1999, Huawei Tech. Co., Ltd.
//File name: 导航数据转换
//Author: 李振  
//edition: 1
//Description:    // 用于详细说明此程序文件完成的主要功能,与其他模块
                  // 或函数的接口,输出值、取值范围、含义及参数间的控
                  // 制、顺序、独立或依赖等关系
//Others:         // 其它内容的说明
//Function List:  // 主要函数列表,每条记录应包括函数名及功能简要说明
//1. ....
//History:        // 修改历史记录列表,每条修改记录应包括修改日期、修改
                  // 者及修改内容简述   
//1. Date:
// Author:
//Modification:
//2. ...
#include <iom16v.h>
#include <macros.h>

#define XTAL 3.6864
#define SS 4
#define MOSI 5
#define MISO 6
#define SCK 7

/******************************************************************************/
/*MAX7219寄存器定义*/
/******************************************************************************/
//寄存器地址定义,'ADD_'替代address
#define ADD_NooP 0x00
#define ADD_digit0 0x01
#define ADD_digit1 0x02  
#define ADD_digit2 0x03
#define ADD_digit3 0x04
#define ADD_digit4 0x05
#define ADD_digit5 0x06
#define ADD_digit6 0x07
#define ADD_digit7 0x08
#define ADD_decodemode 0x09
#define ADD_intensity 0x0A
#define ADD_scanlimit 0x0B
#define ADD_shutdown 0x0C
#define ADD_displaytest 0x0F

//寄存器内容定义,考虑到应用中方便
#define testmode 0x01
//显示测试模式,全亮
#define testend 0x00
//退出测试模式,全灭,等待命令
#define shutdownmode 0x00
//关闭模式
#define normaloperation 0x01
//正常工作模式
#define decodedigit 0xFF
//4位code B解码,D7小数点位,其余位忽略
#define intensitygrade 0x08
//定义亮度级别
#define scandigit 0x07
//扫描8位数码管,单个MAX7219最大的驱动能力

//
/******************************************************************************/
/*系统初始化函数*/
/******************************************************************************/
void port_init(void)//对SPI口和USART设置端口初始状态,别的端口输出低电平
{
PORTA = 0x00;
DDRA  = 0xFF;
PORTB = 0x50;//0b01010000;max7219的CS未选择
DDRB  = 0xBF;//0b10111111;
PORTC = 0x00;//0b01000000;
DDRC  = 0xFF;
PORTD = 0x0D;//0b00001101;
DDRD  = 0xF2;//0b11110010;
}

//SPI初始化
// clock rate: 921599hz
void spi_init(void)
{
SPCR = 0b11010000;//0xDC; //0b11011100;使能SPI中断,传输高位在前,主机模式,相位极性00
SPSR = 0x00; //SPI状态寄存器清零
}

//串口初始化
void uart0_init(void)//不允许中断,baud=9600,8,无校验位
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;//8位数据长度
UBRRL = 0x17; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x18;//接收使能,发送使能
}

/*//看门狗初始化
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling,初始化前先喂狗
WDTCR = 0x08; //WATCHDOG ENABLED - dont forget to issue WDRs
}

//器件总体初始化函数,包括端口初始值,用到器件的功能,和寄存器*/
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
spi_init();
uart0_init();
//watchdog_init();
MCUCR = 0x00;
GICR  = 0x00;//0b00000000不使能外部中断INT0,INT1;//0b11000000使能外部中断INT0,INT1
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

/******************************************************************************/
//延时函数,晶振为8M时,为了计算时间方便
/******************************************************************************/
/*//关闭看门狗程序,为了防止不小心关闭看门狗,需要一个特定的关闭程序
void TDT_OFF(void)
{
WDR();//WDT复位
WDTCR|=(1<<WDTOE)|(1<<WDE);//置位WDTOE和WDE
WDTCR = 0x00;//关闭WDT
}
*/
/******************************************************************************/
//延时函数,晶振为8M时,为了计算时间方便
/******************************************************************************/
//1us级延时
void delay_1us(void)
{
asm("nop");
}

//1us的整倍延时时间
void delay_us(unsigned int n)
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1us();
}

//ms级延时
void delay_1ms(void)
{
unsigned int i;
for(i=1;i<(unsigned int)(XTAL*143-2);i++)
;
}
//1ms的整倍延时时间
void delay_ms(unsigned int n)
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
/******************************************************************************/
/*USART通讯函数*/
/******************************************************************************/
//USART发送子函数
void USART_Transmit(unsigned char data)
{
while(!(UCSRA & (1<<UDRE)));//等待发送缓冲器为空
UDR = data;//将数据放入缓冲器,发送数据  
}

//USART接收子函数
unsigned char USART_Receive(void)
{
while(!(UCSRA & (1<<RXC)));//等待接收数据
return UDR;//从缓冲器中获取并返回数据
}

/******************************************************************************/
/*SPI通讯函数*/
/******************************************************************************/
//SPI主机初始化,另一种初始化写法,这里没有应用
void SPI_MasterInit(void)
{
DDRB = (1<<MOSI)|(1<<SCK);//设置MOSI、SCK输出,其他输入
SPCR = 0xDA;//0b10111010; //使能SPI主机模式,设置时钟速率fck/4
//SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0);
}

//SPI数据发送,主机模式
unsigned char SPI_MasterTransmit(unsigned char Data)
{
SPDR = Data;//启动数据传输  
while(!(SPSR&(1<<SPIF)))//等待传输结束
;
return SPDR;//返回数据
}

//SPI从机初始化
void SPI_SlaveInit(void)
{
DDRB = (1<<MISO);//设置MISO为输出,其他为输入
SPCR = (1<<SPE);//使能SPI
}

//SPI数据接收,从机模式
char SPI_SlaveReceive(void)
{
while(!(SPSR&(1<<SPIF)))//等待接收输结束,若条件成立,执行第一个分号前的语句,这里是空语句
;
return SPDR;//返回数据
  
}

/******************************************************************************/
/*SPI中断函数*/
/******************************************************************************/
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{
USART_Transmit(SPDR);   
}

/******************************************************************************/
/*内带EEPROM通讯函数*/
/******************************************************************************/
//EEPROM不用初始化
//EEPROM写函数
void EEPROM_Write(unsigned int uiAddress,unsigned char ucData)
{
while(EECR&(1<<EEWE))//等待上一次写操作结束
;
EEAR = uiAddress;//设置地址寄存器
EEDR = ucData;//设置数据寄存器
EECR |= (1<<EEMWE);//置位EEMWE
EECR |= (1<<EEWE);//置位EECR启动写操作
}

//EEPROM读函数
unsigned char EEPROM_read(unsigned int uiAddress)
{
while(EECR&(1<<EEWE))//等待上一次写操作结束,否则容易冲突导致读写失败
;
EEAR = uiAddress;//设置地址寄存器
EECR |= (1<<EERE);//置位EECR启动读操作
return EEDR;//返回数据
}

/******************************************************************************/
/*MAX7219初始化*/
/******************************************************************************/
void MAX_Init(void)
{

}                                                                                                                                                  

/******************************************************************************/
/*MAX7219写函数*/
/******************************************************************************/
void Write_Max7219(unsigned char address1,unsigned char dat1,unsigned char address2,unsigned char dat2)
{  
PORTA |= BIT(4);
   SPI_MasterTransmit(address1);  
   SPI_MasterTransmit(dat1);
   SPI_MasterTransmit(address2);  
   SPI_MasterTransmit(dat2);
PORTA &= ~BIT(4);               
}

/******************************************************************************/
/*向MAX7219写入字节(8位)*/
/******************************************************************************/
void sendchar(unsigned char ch)
{
  unsigned char i,temp;
  _NOP();
  for(i=0;i<8;i++)
  {
    temp=ch&0x80;
    ch=ch<<1;
if(temp)
{
   PORTB|=BIT(PB0);
   PORTB&=~BIT(PB2);
   PORTB|=BIT(PB2);
}
else
{
   PORTB&=~BIT(PB0);
   PORTB&=~BIT(PB2);
   PORTB|=BIT(PB2);
}
  }
}

/******************************************************************************/
/*向MAX7219写入字(16位)*/
/******************************************************************************/
void writeword(unsigned char addr,unsigned char num)
{
  PORTB&=~BIT(PB1);
  _NOP();
  sendchar(addr);
  _NOP();
  sendchar(num);
  _NOP();
  PORTB|=BIT(PB1);
}

void initdis(void)
{
  writeword(ADD_scanlimit,scandigit);  //设置扫描界限
  writeword(ADD_decodemode,decodedigit);  //设置译码模式
  writeword(ADD_intensity,intensitygrade); //设置亮度
  writeword(ADD_shutdown,normaloperation); //设置电源工作模式
}

/******************************************************************************/
/*主函数*/
/******************************************************************************/

void main()   
{
init_devices();

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_displaytest);//0x0F
SPI_MasterTransmit(testend);//0X00
PORTA |= BIT(4);

/*delay_ms(100);
USART_Transmit(0x79);
delay_us(10);

PORTA |= BIT(4);
SPI_MasterTransmit(ADD_shutdown);//0x0C
SPI_MasterTransmit(normaloperation);//0x01
PORTA |= BIT(4);

delay_ms(10);
PORTB &= ~BIT(4);
SPI_MasterTransmit(ADD_displaytest);//0x0F
SPI_MasterTransmit(testmode);//0x01
PORTA |= BIT(4);
delay_ms(1000);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_displaytest);//0x0F
SPI_MasterTransmit(testend);//0X00
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_intensity);//0x0A
SPI_MasterTransmit(0x0C);//亮度级别25/32
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_decodemode);//0x09
SPI_MasterTransmit(decodedigit);//0x0F
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_scanlimit);//0x0B
SPI_MasterTransmit(scandigit);//0x07
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_digit0);//0x0B
SPI_MasterTransmit(0x00);//0x07
PORTA |= BIT(4);
*/
PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_digit0);//0x0B
SPI_MasterTransmit(0x00);//0x07
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_digit1);//0x0B
SPI_MasterTransmit(0x01);//0x07
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_digit2);//0x0B
SPI_MasterTransmit(0x02);//0x07
PORTA |= BIT(4);

PORTA &= ~BIT(4);
SPI_MasterTransmit(ADD_digit3);//0x0B
SPI_MasterTransmit(0x03);//0x07
PORTA |= BIT(4);

/*
initdis();
writeword(ADD_displaytest,testmode);
delay_ms(1000);
writeword(ADD_displaytest,testend);
writeword(ADD_digit0,0x00);
writeword(ADD_digit1,0x01);
writeword(ADD_digit2,0x02);
writeword(ADD_digit3,0x03);
writeword(ADD_digit4,0x04);
writeword(ADD_digit5,0x05);
writeword(ADD_digit6,0x06);
writeword(ADD_digit7,0x07);
delay_ms(1000);

//writeword(ADD_digit7,0x07);
*/

}

出0入296汤圆

发表于 2008-5-21 13:32:07 | 显示全部楼层
大哥……我确实没有用过你说的芯片……估计帮不上忙哈……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 00:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表