📄 sz2.c
字号:
#include <iom16.h> //和单片机类型相对应的头文件,选择Atmega16做实验;
#include <macros.h>
#include <spi.h>
void delay_1ms(void); //函数声明,本实验中会用到这两个函数
void delay_nms(unsigned int n);
void InitADC( void);
unsigned int mm;
int EEPROMwrite_256( int location, unsigned char byte);
unsigned char EEPROMread_256( int location);
void SpiWriteByte(unsigned char byte);
unsigned char SpiReadByte(void);
void InitUART( unsigned char baudrate );
unsigned char ReceiveByte( void );
void TransmitByte( unsigned char data );
unsigned char iRx=0;
void timer1_init(void);
void uart0_init(void);
void led( unsigned char ed );
//ICC-AVR application builder : 05-3-12 16:15:07
// Target : M16
// Crystal: 1.0000Mhz
#pragma interrupt_handler UART_RX_interrupt:12 UART_TX_interrupt:14
/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 64 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_RX_BUFFER_MASK 63
#define UART_TX_BUFFER_SIZE 64 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_MASK 63
static unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
unsigned char data=0;
unsigned char RxHead=0;
unsigned int zhongci=0;
unsigned char BUTE1=0xd8;
unsigned char BUTE2=0x34;
unsigned char keyba=0;
unsigned char keyd=0;
unsigned char keyba1=0;
int count=0;
int ci=0;
static unsigned char xianshi[11]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0};
static unsigned char dxianshi[24];
static unsigned char pxianshi[24];
static unsigned char a[60];
static unsigned char b[60];
static unsigned char c[60];
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{
ci++;
c[ci]=SPDR; // 数据暂存a[]中
ci++;
count=count-1;;
if(count>0) SPDR=a[ci];// 未发送完,继续
else
{PORTA=PORTA | 0B10000000;//2510片选// 片选位置低电平 ;
// 否则,片选信号置高电平
PORTB = 0;
}
return;
}
void port_init(void)
{
unsigned char temp ;
DDRA = 0B10000000;
PORTA = 0B10000000;
DDRA = 0B10000000;
PORTB=0;
DDRB = 0B10110000; // Set SCK, MOSI & SS as outputs
PORTB =0; // clear bits MOSI, & SCK
SPCR=0B11010001;
SPSR = 0x00;
temp = SPSR;
temp = SPDR;
PORTB = 0;
PORTC = 0b00000100;
DDRC = 0xff;
PORTC = 0b00000100;
DDRD = 0b11111000;
PORTD = 0b00011000;
}
/* initialize UART */
void InitUART( unsigned char baudrate )
{
UCSRB = 0x00; //disable while setting baud rate
UBRR = baudrate; /* set the baud rate */
/* enable UART receiver and transmitter, and
receive interrupt */
UCR = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
UART_RxTail = 0;
UART_RxHead = 0;
UART_TxTail = 0;
UART_TxHead = 0;
UCSRA = 0x00;
//UCSRC = BIT(URSEL) | 0x06;
//UCSRB = 0xD8;
}
/* interrupt handlers */
void UART_RX_interrupt( void )
{
//unsigned char tmphead;
//data ++; /* read the received data */
/* calculate buffer index */
if ( UART_RxHead > UART_RX_BUFFER_MASK )
{
UART_RxHead=0;/* ERROR! Receive buffer overflow */
}
UART_RxBuf[UART_RxHead] = UDR; /* store received data in buffer */
data=UART_RxBuf[UART_RxHead];
//tmphead = ( UART_RxHead + 1 ) ;
//UART_RxHead = tmphead; /* store new index */
UART_RxHead++;
}
void UART_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART_TxHead != UART_TxTail )
{
/* calculate buffer index */
tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
UART_TxTail = tmptail; /* store new index */
UDR = UART_TxBuf[tmptail]; // start transmition
}
else
{
UCR &= ~(1<<UDRIE); /* disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte( void )
{
unsigned char tmptail;
//if (UART_RxHead==UART_RxTail) return 0;
//while ( UART_RxHead == UART_RxTail ) /* wait for incomming data */
;
tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;/* calculate buffer index */
UART_RxTail = tmptail; /* store new index */
return UART_RxBuf[tmptail]; /* return data */
}
void TransmitByte( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART_TxTail )
;
UART_TxBuf[tmphead] = data; /* store data in buffer */
UART_TxHead = tmphead; // store new index
UCR |= (1<<UDRIE); // enable UDRE interrupt
}
unsigned char DataInReceiveBuffer( void )
{
return ( UART_RxHead != UART_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
void main(void) //主函数
{
unsigned int k=0;
unsigned int i=0;
unsigned char kk=0;
int uuu=4;
int uuj=0;
unsigned char uk=180;
unsigned char jia=0;
unsigned char mi=1;
unsigned char san=0;
InitUART(71);
timer1_init();
MCUCR = 0x02; //TIN0 FALL
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
WDR(); //this prevents a timout on enabling
WDTCR = 0x0C; //WATCHDOG ENABLED - dont forget to issue WDRs
;
port_init();
PORTA = 0B10000000;
PORTC=PORTC & 0B11111011;
delay_nms(40);
PORTA = 0B10000000;
PORTC=PORTC | 0B00000100;
WDR();
RESET2510();// 使芯片复位
delay_nms(600);
WDR();
b[0]=0b10010110;
WR2510(0x0f,1);
//////////////10M晶振 缓冲1:4TQ 缓冲2:4TQ,同步1TQ,传播1TQ,TQ=(2*5/16)*10-6E=625ns
b[0]=0x03;
b[1]=0b10011000;
b[2]=0x04;
WR2510(0x28,3);// 波特率为 160 kbps
/////////////////
b[0]=0x00;
b[1]=0x00;
WR2510(0x20,2);
b[0]=0x00;
b[1]=0x00;
WR2510(0,2);// RX0接收,屏蔽位为0,过滤器为0
b[0]=0x00;
b[1]=0x00;
WR2510(0X20,2);// RX0接收,屏蔽位为0,过滤器为0
b[0]=0x01;
WR2510(0x2b,1);// CAN中断rxb0使能
b[0]=0b00000110;// 设置为正常操作模式
WR2510(0x0f,1);
delay_nms(60);
RD2510(0x0e,1);
b[0]=8;
WR2510(0x35,1);
b[0]=0x03;
b[1]=0X06;
b[2]=0;
WR2510(0x30,3);
b[0]=0;
b[1]=0;
WR2510(0x61,2);
b[0]=0b01100000;
WR2510(0x60,1);
b[0]=8;
WR2510(0x65,1);
b[0]=8;
WR2510(0x75,1);
WDR();
while(1) //程序一直执行该循环
{
WDR( );
if (data!=0)
{
delay_nms(100);
k=UART_RxHead;
b[0]=0x03;
b[1]=0;
b[2]=0;
WR2510(0x30,3);
for(kk=0;kk<k;kk++)
TransmitByte(UART_RxBuf[kk]);
UART_RxHead=0;
RxHead=0;
}
RD2510(0x2c,1);
if ((c[2] & 0b00000001)>0)
{
RD2510(0x66,8);
for(i=0;i<8;i++)
TransmitByte(c[2+i]);
/b[0]=0b11000110;
b[1]=0;
for(kk=0;kk<8;kk++)
for(i=2;i<8;i++)
b[i]=UART_RxBuf[i]+c[2+i];
for(i=0;i<8;i++)
WR2510(0x36,8);
RTS2510();// 发送
b[0]=0x00;
WR2510(0x2c,1);// CAN中断清除
}
}
WDR(); //this prevents a timout on enabling
//WDTCR = 0x0C; //WATCHDOG ENABLED - dont forget to issue WDRs
}
void delay_1ms(void)//1ms延时函数
{
unsigned int i;
for (i=0;i<2;i++)
{
}
}
void delay_nms(unsigned int n)//延时n毫秒
{
unsigned int i;
for (i=0;i<n;i++)//执行n次1毫秒延时
delay_1ms();
}
///////////////////////
// 启动SPI传送
void SPIEXCHANGE()
{
unsigned char k;
unsigned char kk;
ci=0;
if(count>0) {// 有数据可送?
PORTA=PORTA & 0B01111111;//2510片选// 片选位置低电平
SPDR=a[0];;// 送数
//while (!(SPSR & 0x80));
// kk=SPSR;
//kk = SPDR;
;
}
else
;// 否则,空操作,并返回
return;
}
// 等待SPI传送完成
void WAIT_SPI()
{
do{
;
}while(count>0);// 当count!=0时,等待 to add "CLRWDT"
return;
}
// 对MCP2510芯片进行复位
void RESET2510()
{
a[0]=0B1100000;
count=1;
SPIEXCHANGE();// 送复位指令
WAIT_SPI();
return;
}
// 读取从地址"adress"开始的寄存器中的数据,共n个,存放在数组b[n]中
int RD2510(adress,n)
int adress;
int n;
{
int j;
a[0]=3;
a[1]=adress;
for(j=0;j<n;j++) c[j+2]=0;
count=n+2;// 指令、地址和要得到的数据量n
SPIEXCHANGE();
WAIT_SPI();
for(j=0;j<n;j++) b[j]=c[j+2];// 数据存到数组b[]中
return;
}
// 向从地址"adress"开始的寄存器写入数据,共n个,数据存放数组b[n]中
void WR2510(int adress,int n)
{
int j;
a[0]=2;
a[1]=adress;
for(j=0;j<n;j++) a[j+2]=b[j];
count=n+2;// 指令、地址和要写入的数据量n
SPIEXCHANGE();
WAIT_SPI();
return;
}
// MCP2510芯片请求发送程序
void RTS2510()
{
a[0]=0b10000001;
count=1;
SPIEXCHANGE();// 发送MCP2510芯片,请求发送指令
WAIT_SPI();
return;
}
// 读取MCP2510芯片的状态
int GETS2510()
{
a[0]=0b10100000;
c[1]=0;
c[2]=0;
count=2;
SPIEXCHANGE();// 读取MCP2510芯片状态
WAIT_SPI();
b[0]=c[1];// 状态存到数组b[]中
b[1]=c[2];
return;
}
// 对MCP2510芯片进行位修改子程序
void BM2510(adress,mask,data)
int adress;
int mask;
int data;
{
a[0]=00000101;// 位修改指令
a[1]=adress;// 位修改寄存器地址
a[2]=mask;// 位修改屏蔽位
a[3]=data;// 位修改数据
count=4;
SPIEXCHANGE();
WAIT_SPI();
return;
}
// 设置MCP2510芯片为正常操作模式
void SETNORMAL()
{
int k=1;
BM2510(0xf,0xe0,0b10000000);// 设置为正常操作模式 //////改为回环
do{
RD2510(0x0e,1);
k=c[2]&0xe0;
TransmitByte(c[2]);
}while(k);// 确认已进入正常操作模式
return;
}
// 对MCP2510进行初始化
void INIT2510()
{
//RESET2510();// 使芯片复位
delay_nms(4000);
RD2510(0x0e,1);
TransmitByte(c[2]);
b[0]=0x02;
b[1]=0x90;
b[2]=0x07;
WR2510(0x28,3);// 波特率为 125 kbps
b[0]=0x00;
b[1]=0x00;
WR2510(0x20,2);
b[0]=0x00;
b[1]=0x00;
WR2510(0,2);// RX0接收,屏蔽位为0,过滤器为0
b[0]=0x00;
WR2510(0x2b,1);// CAN中断不使能
SETNORMAL();// 设置为正常操作模式
//b[0]=0x00;
//WR2510(0xe,1);
return;
}
// MCP2510芯片发送完成与否判断,邮箱号为adress
void TXCOMPLETE(adress)
int adress;
{
int k=1;
do{
RD2510(adress,1);
k=b[0]&0x08;
}while(k);// 确认是否已发送完毕 to add CLRWDT
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -