RC4算法的430实现
RC4算法的MSP430实现,本程序中包括按键消抖、SPI传输数据、中断函数、
#include <MSP430x14x.h> unsigned char keypoint=0; unsigned char Rpoint=0; int i; unsigned char R_buff[8]; unsigned char T_buff[4]; unsigned char RR_buff[4]; char s_box[256]; void getkey(unsigned char *key,int key_len, char *s_box); void main(void) { WDTCTL = WDTPW + WDTHOLD; /*停止看门狗定时器,即为OX5a80*/ DCOCTL=0xE0; //DCOCLK选择最低频率, BCSCTL1=0x85; // 使XT2振荡器关闭,选择中间的标称频率。 BCSCTL2=0x00; //MCLk和SMCLk时钟源都选择DCOCLK,并且都为1分频,DCO采用内部电阻。 P2DIR=0x00; //设置P2端口为输入模式 P2IE=0x00; //将中断寄存器清零 P2IES=0x00; P2IFG=0x00; P2IE |=BIT3; //P2.3口中断使能,p2.3为确认键,低电平有效 P2IES |=BIT3; P1DIR=0x0F; //p1.0-P1.3方向为输出,PxDIR复位后默认为0 P1OUT=0x00; //P1口输出寄存器清零,输出低电平 P1IE=0x00; //将中断寄存器清零 P1IES=0x00; P1IFG=0x00; //使能P1.4-P1.7口中断 //对应的管脚由高到低电平跳变使相应的标志置位,下降沿有效 P1IE |= BIT4; P1IES |= BIT4; P1IE |= BIT5; P1IES |= BIT5; P1IE |= BIT6; P1IES |= BIT6; P1IE |= BIT7; P1IES |= BIT7; UCTL0 |= CHAR+SYNC+MM+SWRST; //SPI主模式,8位数据 UTCTL0=CKPH+SSEL1+STC; //3线SPI模式,时钟源选择辅助时钟SMCLK,时钟信号延迟半个周期 UBR00=0x04; //设置波特率选择寄存器,4分频 UBR10=0x00; UMCTL0=0x00; //波特率调整寄存器复位 UCTL0 &= ~SWRST; // 初始化USART状态机,置SWRST=0,SPI使能 P3SEL |=0x0F; //P3.1-P3.3为模块占用 P3DIR=0x0A; P4DIR |=0x03; //P4.0为STE信号线,p4.0方向为输出 ME1 |=USPIE0; //SPI0模块允许 // IE1 |= URXIE0; // RX interrupt enable P4OUT |= BIT0; P4OUT |= BIT1; _EINT(); /* Enable interrupts */ while(1) { LPM0; _NOP(); } } /******延迟,用于消除抖动。******/ void delay(){ unsigned char temp; for (temp=0xff;temp>0;temp--); } /*****检查按键,确认按键。*****/ unsigned char key(void) { unsigned char x; P1DIR=0x0F;//设置p1.0-p1.3为输出模式,p1.4-p1.7为输入模式 P1OUT=0x07; //扫描第一行,使得P1.3为低,而观察P1.4-P1.7的电平 0000 0111 switch(P1IN&0xF0) { case 0xE0: x=0; //p1.4为低 P1IN=1110 0111 break; case 0xD0: x=1; //p1.5为低 P1IN=1101 0111 break; case 0xB0: x=2; break; case 0x70: x=3; break; default: P1OUT=0x0B; //扫描第二行,使得p1.2为低电平 switch(P1IN&0xF0) { case 0xE0: x=4; break; case 0xD0: x=5; break; case 0xB0: x=6; break; case 0x70: x=7; break; default: P1OUT=0x0D; //扫描第三行 switch(P1IN&0xF0) { case 0xE0: x=8; break; case 0xD0: x=9; break; case 0xB0: x=10; break; case 0x70: x=11; break; default: P1OUT=0x0E;//扫描第四行 switch(P1IN&0xF0) { case 0xE0: x=12; break; case 0xD0: x=13; break; case 0xB0: x=14; break; case 0x70: x=15; break; } } } } return (x); } /*****判断有无按键按下*****/ unsigned char keyj(void) { unsigned char z; P1DIR=0x0F; //设置P1.0-P1.3为输出模式,p1.4-p1.7为输入模式 P1OUT=0x00; //设置P1OUT输出低电平 z=(~(P1IN)&0xF0); // 求X的值,P1IN高四位至多只有一位为低,即有键按下 return(z); // 无按键,返回 0; 有按键返回 非0 } unsigned char keyf(void) { unsigned char z; P2DIR=0x00; //设置p2端口为输入模式 z=(P2IN&0x08); // 求X的值 0000 1000 确认P2.3是否有输入 return(z); // 无按键,返回 0; 有按键返回 非0 } #pragma vector=PORT1_VECTOR __interrupt void port1key(void) //定义中断服务函数 { if(keypoint<8) { if(keyj()!=0x00) //判断有无按键按下 { delay() ; //消抖动 if(keyj()!=0x00) //再判断有无按键按下 { R_buff[keypoint]=key(); //按键键值保存到队列 keypoint++; } } } P1OUT=0x00; P1IFG=0x00; //清除中断标志 } /*****组合队列(将8个8位二进制数变为4个8位2进制数,实际是将高四位0去掉)******/ void keyin() { T_buff[0]=R_buff[0]*2*2*2*2+R_buff[1]; T_buff[1]=R_buff[2]*2*2*2*2+R_buff[3]; T_buff[2]=R_buff[4]*2*2*2*2+R_buff[5]; T_buff[3]=R_buff[6]*2*2*2*2+R_buff[7]; } /*****SPI模块初始化程序*****/ void initspi(void) { UCTL0 |= CHAR+SYNC+MM+SWRST; //SPI主模式,8位数据,并使得SWRST=1 UTCTL0=CKPH+SSEL1+STC; //3线SPI模式,时钟源选择辅助时钟SMCLK UBR00=0x03; //设置波特率选择寄存器,3分频,SMCLK/3 UBR10=0x00; UMCTL0=0x00; //波特率调整寄存器复位 UCTL0 &= ~SWRST; // 初始化USART状态机,置SWRST=0,SPI使能 P3SEL |=0x0F; //P3.1-P3.3为模块占用 P4DIR |=0x01; //P4.0为STE信号线,p4.0方向为输出 ME1 |=USPIE0; //SPI0模块允许 } #pragma vector=PORT2_VECTOR __interrupt void port2keyaffirm(void) { if(keyf()==0x00) //判断有无按键按下 { delay() ; //消抖动 if(keyf()==0x00) //判断有无按键按下 { /*initspi();*/ Rpoint=0; for(i=keypoint;i<8;i++) //判断键入初始密码是否为8个,不足补0 { R_buff[i]=0; } keyin(); getkey(R_buff,8, s_box); for(i=0;i<4+256;i++) //将4个组合后的8位二进制数发送给FPGA { if (i<4) P4OUT |= BIT0;//P4.0输出高电平(有效),SIMO和UCLK正常操作 else P4OUT |= BIT1; _NOP(); //SIMO从进主出,主机模式下为数据输出引脚 _NOP(); //UCLK为USART时钟,主机模式为输出时钟 _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); while(!(IFG1 & UTXIFG0)); if (i<4) P4OUT &=~(BIT0);//P4.0输出高电平(有效),SIMO和UCLK正常操作 else P4OUT &=~(BIT1);//p4.0输出低电平,使FPGA的移位寄存器开始工作, if(i<4) TXBUF0=T_buff[i];//SIMO和UCLK被强制进入到输入状态 else TXBUF0=s_box[i-4]; while(!(IFG1 & UTXIFG0)); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); if (i<4) P4OUT |= BIT0;//P4.0输出高电平(有效),SIMO和UCLK正常操作 else P4OUT |= BIT1;//P4.0输出高电平,SIMO和UCLK正常工作 } keypoint=0; P2IFG=0x00; //清除中断标志 } } } #pragma vector=USART0RX_VECTOR __interrupt void SPI0_rx (void) { RR_buff[Rpoint]= RXBUF0;//RXBUF0接收数据缓存 Rpoint++; TXBUF0=0xFF;//TXBUF0发送数据缓存,可复位UTxIFGx } void getkey(unsigned char *key,int key_len, char *s_box) { int i=0; int j=0; char temp; for(i=0;i<256;i++) s_box[i]=i; for(i=0;i<256;i++) { j=(j+key[i%key_len]+s_box[i])%256; temp=s_box[i]; s_box[i]=s_box[j]; s_box[j]=temp; } }
路漫漫其修远兮,吾将上下而求索