一般教科书上提供的UART收发的程序往往是一段采用轮循(Polling)方式完成收发的简单代码。但对于高速的AVR来讲,采用这种方式大大降低了MUC的效率。在使用AVR时,应根据芯片本身的特点(片内大容量数据存储器RAM,更适合采用高级语言编写系统程序),编写高效可靠的UART收发接口(低层)程序。下面是一个典型的USART的接口程序。(下面是CodeVisionAVR修改成WINAVR后的程序,原来的程序请看底下给出的链界,在http://www.ouravr.com/的论坛里)

/*****************************************************

// usart.h

// 常量定义
 #define  BAUDRATE        9600     // 波特率
 // #define F_CPU            4000000   // 晶振频率4.0MHz

#define  RXB8 1
 #define  TXB8 0
 #define  PE 2     // M16
 // #define UPE 2     // M128
 #define  OVR 3
 #define  FE 4
 #define  UDRE 5
 #define  RXC 7

// 宏定义
 #define  FRAMING_ERROR (1<<FE)
 #define  PARITY_ERROR (1<<PE)     // M16
 // #define PARITY_ERROR (1<<UPE)     // M128
 #define  DATA_OVERRUN (1<<OVR)
 #define  DATA_REGISTER_EMPTY (1<<UDRE)
 #define  RX_COMPLETE (1<<RXC)

//  USART Receiver buffer
 //  全局变量,会在中断服务程序中被修改,须加volatile限定,不要就会出错啦
 #define  RX_BUFFER_SIZE 16          //  接收缓冲区大小,可根据需要修改
 volatile   char  rx_buffer[RX_BUFFER_SIZE];  //  接收缓冲区,为char型变量组成的数组,该数组构成环形队列,个数为RX_BUFFER_SIZE 
 volatile  unsigned  char  rx_wr_index,rx_rd_index,rx_counter;
 //  This flag is set on USART Receiver buffer overflow
 volatile   char  rx_buffer_overflow;    // 接收缓冲区溢出标志

//  USART Transmitter buffer
 #define  TX_BUFFER_SIZE 16
 volatile   char  tx_buffer[TX_BUFFER_SIZE];
 volatile  unsigned  char  tx_wr_index,tx_rd_index,tx_counter;

//  函数声明
 char  get_c( void );
 void  put_c( char  c);
 void  put_s( char   * ptr);
 void  init_USART( void );

// usart.c

#include  < avr / io.h >
#include  < stdio.h >
#include  < avr / interrupt.h >
#include  " usart.h "

/*接收中断*/
ISR(USART_RXC_vect)
 {
    char status,data;
    status=UCSRA;     //读取接收状态标志位,必须先读,当读了UDR后,UCSRA便自动清零了  
    data=UDR;         //读取USART数据寄存器,这句与上句位置不能颠倒的
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)     //判断本接收到的数据是否有数据帧、校验或数据溢出错误(此处指USART的硬件接收溢出)
       {
           rx_buffer[rx_wr_index]=data;   // 将数据填充到接收缓冲队列中
           if (++rx_wr_index == RX_BUFFER_SIZE)    //写指针指向下一个单元,并判断是否到了队列的尾部,(不表示接受缓冲区是否满!)
               rx_wr_index=0;  //到了尾部,则指向头部(构成环状)
           if (++rx_counter == RX_BUFFER_SIZE)     //队列中收到字符加1,并判断是否队列已满 
          {
              rx_counter=0;   // 队列满了,队列中收到字符个数为0,表示队列中所有以前的数据作废,因为最后的数据已经把最前边的数据覆盖了
              rx_buffer_overflow=1;        //置缓冲区溢出标志。在主程序中必要的地方需要判断该标志,以证明读到数据的完整性
          };
       };
}
 /*接收单个字符*/
 char  get_c( void )
 {
    char data;
    while (rx_counter==0);             //接收数据队列中没有数据可以读取,等待......(注2)
    data=rx_buffer[rx_rd_index];       //读取缓冲队列中的数据
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;     //读取指针指向下一个未读的数据,如果指到了队列尾部,则指回到队列头步
    cli();    // 关中断!非常重要
    --rx_counter;  //队列中未读数据个数减1。因为该变量在接收中断中要改变的,为了防止冲突,所以改动前临时关闭中断。程序相当可靠了。
    sei();    // 开中断
    return data;
}

// 发送中断
 ISR(USART_TXC_vect)
 {
    if (tx_counter)
    {
           --tx_counter;
           UDR=tx_buffer[tx_rd_index];
           if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
    }; 
}
 /*发送单个字符*/
 void  put_c( char  c)
 {
    while (tx_counter == TX_BUFFER_SIZE);   //发送数据队列中还有数据没有发送完,等待
    cli();
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))    //若发送数据队列有数据或者数据寄存器UDR非空时执行(因为队列先进先出的原因,所以,c要放进非空的发送数据队列里面)
       {
           tx_buffer[tx_wr_index]=c;
           if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
           ++tx_counter;
       }
    else
           UDR=c;
    sei();
}
 /*发送字符串*/
 void  put_s( char   * ptr)
 {
    while (*ptr)
    {
        put_c(*ptr++);
    }
    put_c(0x0D);
    put_c(0x0A);  //结尾发送回车换行
}

/*USART 初始化*/
 void  init_USART( void )
 {

//USART 9600 8, n,1  PC上位机软件(超级终端等)也要设成同样的设置才能通讯
    UCSRC = (1<<URSEL) | 0x06;
    UBRRL= (F_CPU/BAUDRATE/16-1)%256;
    UBRRH= (F_CPU/BAUDRATE/16-1)/256;
    UCSRA = 0x00;
    //接收使能,发送使能,接收中断使能,发送中断使能
    UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
}

/***********************************************
**** 名  称:AVR USART(RS232)低层驱动+中间层软件示例        
****                                          
**** 作  者:zhiyu                       
**** 编译器:WINAVR20070525                   
****                                         
**** 参  考:http://www.ouravr.com/bbs/bbs_content.jsp?mother_form=bbs_content.jsp&bbs_id=1000&bbs_page_no=1&bbs_sn=147242
             《高档8位单片机ATmega128原理与开发应用指南(上)》--马潮  P320
             《嵌入式C编程与ATMEL AVR》-- 国外计算机经典教材 P141
**** 日  期:2007.07.19
****
**** 芯  片:M16L
**** 时钟源:外部4M晶振
****
**** 结  果:测试成功
**** 问  题:暂无
***********************************************/
 // #include <avr/io.h>
 // #include <stdio.h>
 #include  < avr / interrupt.h >
#include  " usart.h "

int  main( void )
 {
    init_USART();
    sei();    //总中断允许
    
    put_s("Hello!");
    put_s("这是一个简单的高速的串口驱动程序");
    put_s("请你输入任意的字符,单片机将返回你输入的字符");
    while (1)
    {
        put_c(get_c());
    }
}

// Makefile,主要的几项,只是针对我这里的程序,要灵活运用哦

MCU  =  atmega16

F_CPU  =   4000000

TARGET  =  main

SRC  =  $(TARGET).c usart.c    // 多文件编译才会用到这一项,可以参考这个帖子:

http: // www.mcublog.com/blog/user1/4266/archives/2006/6145.html

*****************************************************/

这段由CVAVR程序生成器产生的UART接口代码是一个非常好的、高效可靠,并且值得认真学习和体会的。其特点如下:
   l.它采用两个8字节的接收和发送缓冲器来提高MCU的效率.当主程序调用getchar()函数时,按顺序执行到while (rx_counter==0)处,接收数据队列里面就没有数据,如果再没有数据输入,那么就只能死在那里等待.如果有数据输入的话,中断很快就响应,数据就会迅速地填充接收数据队列,rx_counter!=0,这个死等待也就给瓦解了,让程序执行接下来的那句data=rx_buffer[rx_rd_index]了.最后return data;,返回输入的值;如当主程序调用Putchar()发送数据时,如果UART口不空闲,就将数据放入发送缓冲器中,MCU不必等待,可以继续执行其它的工作。而UART的硬件发送完一个数据后,产生中断,由中断服务程序负责将发送缓冲器中数据依次自动送出。

C语言书本里有其中一段:

getchar()函数(字符输入函数)的作用是从终端(或系统隐含指定的输入设备)输入一个字符.getchar()函数没有参数.当你输入一个字符时候,比如'a'后,要按'Enter'键,字符才能送到内存!你一旦按了这个'Enter',上面的程序就会执行中断响应了,
   2.数据缓冲器结构是一个线性的循环队列,由读、写和队列计数器3个指针控制,用于判断队列是否空、溢出,以及当前数据在队列中的位置。
   3.用编译控制命令#pragma savereg-和#pragma savereg+,使得由CVAVR在生成的中断服务程序中不进行中断保护(CVAVR生成中断保护会将比较多的寄存器压入堆栈中),而在中断中嵌入汇编,只将5个在本中断中必须要保护的寄存器压栈。这样提高了UART中断处理的速度,也意味着提高了MCU的效率。
   4.由于在接口程序Putchar()、Getchar()和中断服务程序中都要对数据缓冲器的读、写和队列计数器3个指针判断和操作,为了防止冲突,在Putchar()、Getchar()中对3个指针操作时临时将中断关闭,提高了程序的可靠性。
    建议读者能逐字逐句地仔细分析该段代码,真正理解和领会每一句语句(包括编译控制命令的作用)的作用,从中体会和学习如何编写效率高,可靠性好,结构优良的系统代码。这段程序使用的方法和技巧,对编写SPI、I2C的串行通信接口程序都是非常好的借鉴。
    作为现在的单片机和嵌入式系统的工程师,不仅要深入全面的掌握芯片和各种器件的性能,具备丰富的硬件设计能力;同时也必须提高软件的设计能力。要学习和掌握有关数据结构、操作系统、软件工程、网络协议等方面的知识,具有设计编写大的复杂系统程序的能力。

/*=================================================

链接: http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=147242&bbs_page_no=1&sub_kind_id=1430&bbs_id=1000

http://www2.ouravr.com/bbs/bbs_content.jsp? mother_form=bbs_content.jsp&amp;bbs_id=1000&amp;bbs_page_no=1&amp;bbs_sn=528742

http://bbs.avrvi.com/simple/index.php?t3193.html

书籍: 高档8位单片机ATmega128原理与开发应用指南(上) P320

嵌入式C编程与Atmel AVR P141 第三章 标准I/O和预处理函数 (网上有这本电子书的下载)

下面是马潮老师的说法:

在CVAVR系统提供的标准库函数stdio.h中,提供了getchar()函数,该函数是采用轮询方式从USART接收数据的,轮询方式不仅效率低,而且会丢失数据,不能实现多任务的并行处理。

CVAVR程序向导中给出的采用中断+缓冲的方式接受数据,同PC的串口接收数据的方法一样,充分利用了AVR的高速和RAM多的优点,体现出了如何才能充分发挥AVR的特点的程序设计思想,这种思路在32位系统中也是这样的。

使用AVR的话,对软件的设计能力要求更高了,否则根本不能发挥和体现AVR的特点。许多人有了一点C的基础,就认为采用C编写单片机程序没问题,很快就会掌握AVR了,对此我只能一笑了之。看看本站上众多的代码,再看看本贴的遭遇,能说什么呢?

还有,你可以参考一下这里的链接:http://www.iccavr.com/forum/dispbbs.asp?boardID=2&ID=2249&page=1这人朋友些得不错,主要是因为:

#define  RX_BUFFER_SIZE0 8  // 收件箱的长度

unsigned  char  rx_buffer0[RX_BUFFER_SIZE0];    // 收信箱
 unsigned  char  rx_wr_index0;    // 收信箱写指针
 unsigned  char  rx_rd_index0;    // 收信箱读指针
 unsigned  char  rx_counter0;     // 收信箱存量
 unsigned  char  rx_buffer_overflow0;   // 收信箱满标志位

这样的比喻不是很好理解了吗,你要是脑子发散一点,会不会想到操作系统里面的"管道"的概念呢,其实现在我也没具体去看这东西,不过也会有些相通的地方吧.

回到本题:
注1:
如果在程序的开头部分加上语句
#define _DEBUG_TERMINAL_IO_
那么程序在编译时仍使用系统自己的getchar()函数,这样在软件模拟仿真时,可以从模拟的终端读取数据,便于在软件模拟环境中调试整个系统,而需要正式运行时,则把该句注释掉。
注2:
此处在正式应用中应根据实际情况做适当的修改。否则当主程序调用getchar()时,如果缓冲队列中没有数据,同时对方也没有发数据的情况时,程序会在此死循环。
比较简单的办法是将这句删掉,而在调用getchar()函数前先判断rx_counter的值,为0的话就不调用了。
或改为:

signed  int  getchar( void )  
   {  
    signed int data;  
    if (rx_counter == 0) 
    { 
        data = -1;     
    } 
    else 
    { 
        data=rx_buffer[rx_rd_index];   //读取缓冲队列中的数据  
        if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;  //读取指针指向下一个未读的数据,如果指到了队列尾部,则指回到队列头步  
        #asm("cli")      // 关中断!非常重要                                               
        --rx_counter;    //队列中未读数据个数减1。因为该变量在接收中断中要改变的,为了防止冲突,所以改动前临时关闭中断。程序相当可靠了。  
        #asm("sei")      // 开中断 
    } 
    return data;  
}

注3:
有兴趣希望深入实在学习的网友,可将CVAVR生成的USART发送代码仔细分析以下。它的发送代码非常完美,可以马上使用。
思考分析:

#include  < mega16.h >

#define  RXB8 1 
 #define  TXB8 0 
 #define  UPE 2 
 #define  OVR 3 
 #define  FE 4 
 #define  UDRE 5 
 #define  RXC 7

#define  FRAMING_ERROR (1<<FE) 
 #define  PARITY_ERROR (1<<UPE) 
 #define  DATA_OVERRUN (1<<OVR) 
 #define  DATA_REGISTER_EMPTY (1<<UDRE) 
 #define  RX_COMPLETE (1<<RXC)

//  USART Transmitter buffer 
 #define  TX_BUFFER_SIZE 8 
 char  tx_buffer[TX_BUFFER_SIZE];

#if  TX_BUFFER_SIZE<256 
unsigned  char  tx_wr_index,tx_rd_index,tx_counter; 
 #else  
unsigned  int  tx_wr_index,tx_rd_index,tx_counter; 
 #endif

//  USART Transmitter interrupt service routine 
 interrupt [USART_TXC]  void  usart_tx_isr( void ) 
 { 
if (tx_counter) 
   { 
   --tx_counter; 
   UDR=tx_buffer[tx_rd_index]; 
   if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0; 
   }; 
}

#ifndef _DEBUG_TERMINAL_IO_ 
 //  Write a character to the USART Transmitter buffer 
 #define  _ALTERNATE_PUTCHAR_ 
 #pragma  used+ 
 void  putchar( char  c) 
 { 
while (tx_counter == TX_BUFFER_SIZE); 
#asm("cli") 
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0)) 
   { 
   tx_buffer[tx_wr_index]=c; 
   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0; 
   ++tx_counter; 
   } 
else 
   UDR=c; 
#asm("sei") 
}  
 #pragma  used- 
 #endif

//  Standard Input/Output functions 
 #include  < stdio.h >

//  Declare your global variables here

void  main( void ) 
 { 
// Declare your local variables here

// Input/Output Ports initialization 
// Port A initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTA=0x00; 
DDRA=0x00;

// Port B initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTB=0x00; 
DDRB=0x00;

// Port C initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTC=0x00; 
DDRC=0x00;

// Port D initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTD=0x00; 
DDRD=0x00;

// Timer/Counter 0 initialization 
// Clock source: System Clock 
// Clock value: Timer 0 Stopped 
// Mode: Normal top=FFh 
// OC0 output: Disconnected 
TCCR0=0x00; 
TCNT0=0x00; 
OCR0=0x00;

// Timer/Counter 1 initialization 
// Clock source: System Clock 
// Clock value: Timer 1 Stopped 
// Mode: Normal top=FFFFh 
// OC1A output: Discon. 
// OC1B output: Discon. 
// Noise Canceler: Off 
// Input Capture on Falling Edge 
// Timer 1 Overflow Interrupt: Off 
// Input Capture Interrupt: Off 
// Compare A Match Interrupt: Off 
// Compare B Match Interrupt: Off 
TCCR1A=0x00; 
TCCR1B=0x00; 
TCNT1H=0x00; 
TCNT1L=0x00; 
ICR1H=0x00; 
ICR1L=0x00; 
OCR1AH=0x00; 
OCR1AL=0x00; 
OCR1BH=0x00; 
OCR1BL=0x00;

// Timer/Counter 2 initialization 
// Clock source: System Clock 
// Clock value: Timer 2 Stopped 
// Mode: Normal top=FFh 
// OC2 output: Disconnected 
ASSR=0x00; 
TCCR2=0x00; 
TCNT2=0x00; 
OCR2=0x00;

// External Interrupt(s) initialization 
// INT0: Off 
// INT1: Off 
// INT2: Off 
MCUCR=0x00; 
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization 
TIMSK=0x00;

// USART initialization 
// Communication Parameters: 8 Data, 1 Stop, No Parity 
// USART Receiver: Off 
// USART Transmitter: On 
// USART Mode: Asynchronous 
// USART Baud rate: 9600 
UCSRA=0x00; 
UCSRB=0x48; 
UCSRC=0x86; 
UBRRH=0x00; 
UBRRL=0x19;   //波特率设置有疑问待议  2021.9.30

// Analog Comparator initialization 
// Analog Comparator: Off 
// Analog Comparator Input Capture by Timer/Counter 1: Off 
ACSR=0x80; 
SFIOR=0x00;

// Global enable interrupts 
#asm("sei")

while (1) 
      { 
      // Place your code here 
      putchar(0x55); 
      }; 
}

我在主程序的循环里仅有一句不停的发0X55,问题是AVR的运行速度非常快,而USART串出的速度肯定明显的慢(按9600bps计算,需要1秒多时间才能送出1000个字符),那么,假定主程序循环了1000次,发送1000个0x55,请判断在UASRT口上能否正确的发出1000个0x55,有没有丢失或溢出现象存在?

答:不会。因为putchar()中有这句:

while (tx_counter == TX_BUFFER_SIZE);

表示如果缓冲满就等待
======================================================*/
————————————————
版权声明:本文为CSDN博主「zhiyu520」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhiyu520/article/details/1795332

MEGA2560头文件中断相量定义

// Interrupt vectors definitions

#define EXT_INT0 2
#define EXT_INT1 3
#define EXT_INT2 4
#define EXT_INT3 5
#define EXT_INT4 6
#define EXT_INT5 7
#define EXT_INT6 8
#define EXT_INT7 9
#define PC_INT0 10
#define PC_INT1 11
#define PC_INT2 12
#define WDT 13
#define TIM2_COMPA 14
#define TIM2_COMPB 15
#define TIM2_OVF 16
#define TIM1_CAPT 17
#define TIM1_COMPA 18
#define TIM1_COMPB 19
#define TIM1_COMPC 20
#define TIM1_OVF 21
#define TIM0_COMPA 22
#define TIM0_COMPB 23
#define TIM0_OVF 24
#define SPI_STC 25
#define USART0_RXC 26
#define USART0_UDRE 27
#define USART0_TXC 28
#define ANA_COMP 29
#define ADC_INT 30
#define EE_RDY 31
#define TIM3_CAPT 32
#define TIM3_COMPA 33
#define TIM3_COMPB 34
#define TIM3_COMPC 35
#define TIM3_OVF 36
#define USART1_RXC 37
#define USART1_UDRE 38
#define USART1_TXC 39
#define TWI 40
#define SPM_READY 41
#define TIM4_CAPT 42
#define TIM4_COMPA 43
#define TIM4_COMPB 44
#define TIM4_COMPC 45
#define TIM4_OVF 46
#define TIM5_CAPT 47
#define TIM5_COMPA 48
#define TIM5_COMPB 49
#define TIM5_COMPC 50
#define TIM5_OVF 51
#define USART2_RXC 52
#define USART2_UDRE 53
#define USART2_TXC 54
#define USART3_RXC 55
#define USART3_UDRE 56
#define USART3_TXC 57

#define USART_RXC USART0_RXC
#define USART_DRE USART0_UDRE
#define USART_TXC USART0_TXC

最后三个宏定义相当于把USART_RXC等三定义默认为串口0的宏定义

MEGA16头文件中中断相量定义

// Interrupt vectors definitions

#define EXT_INT0 2
#define EXT_INT1 3
#define TIM2_COMP 4
#define TIM2_OVF 5
#define TIM1_CAPT 6
#define TIM1_COMPA 7
#define TIM1_COMPB 8
#define TIM1_OVF 9
#define TIM0_OVF 10
#define SPI_STC 11
#define USART_RXC 12
#define USART_DRE 13
#define USART_TXC 14
#define ADC_INT 15
#define EE_RDY 16
#define ANA_COMP 17
#define TWI 18
#define EXT_INT2 19
#define TIM0_COMP 20
#define SPM_READY 21

CVAVR生成的典型USART收发的接口程序(MEGA16只有一个串口所以不用区分是哪个串口的中断相量编号,而MEGA2560多个串口,在头文件中就区分开多个串口的中断相量编号,参考各自头文件)相关推荐

  1. 编写一个汇编语言程序,有一个50个数据的数据区,找出最大数和最小数,分别存放在AX和BX寄存器中

    [微机原理]-汇编题 编写一个汇编语言程序,有一个50个数据的数据区,找出最大数和最小数,分别存放在AX和BX寄存器中. DATA SEGMENT NUM DB 21H,34,23H...DATA E ...

  2. linux表示逻辑分区的标号,在Linux系统的设备文件中,代表第2个SCSI硬盘的第1个逻辑分区的设备文件是()。...

    精益生产方式的两大支柱是()A.准时化B.自动化C.标准化D.理论化 以下哪些是属于可视化管理()A.颜色条线B.安全警示C.管理看板D.操作规范 全面实行精益生产的企业包括以下几个方面()A.产品精 ...

  3. js文件中可以写html吗,js代码写在HTML正常,分离成js文件再在HTML中引用不起作用...

    js代码写在HTML功能正常,分离成js文件再在HTML中引用却不起作用 js代码片段,功能是调用高德地图JS API,并做些布局调整 var map = new AMap.Map("con ...

  4. 有两个磁盘文件 textl.txt text2.txt ,各存放一行英文字母,要求把这两个文件中的信息合并(按字母顺序排列),然后输出到 个新文件 text3.txt

    import fileinput a = [] with fileinput.input(files=('text1.txt','text2.txt')) as fp:for line in fp:a ...

  5. 解决方案:ppt打不开,显示发现文件中的内容有问题。可尝试修复此演示文稿

    解决方案:ppt打不开,显示发现文件中的内容有问题.可尝试修复此演示文稿 参考文章: (1)解决方案:ppt打不开,显示发现文件中的内容有问题.可尝试修复此演示文稿 (2)https://www.cn ...

  6. java中secretkey,java生成秘钥key,并保存秘钥到文件中

    本例子采用的是Java的对称加密其中的一种方式(3DES),其他的加密方式也类似.生成一个key秘钥,发送方使用生成的key秘钥进行加密操作,然后把生成的key秘钥保存到文件中,提供给需要解密的一方使 ...

  7. java项目的秘钥怎么保存_java生成秘钥key,并保存秘钥到文件中

    本例子采用的是Java的对称加密其中的一种方式(3DES),其他的加密方式也类似.生成一个key秘钥,发送方使用生成的key秘钥进行加密操作,然后把生成的key秘钥保存到文件中,提供给需要解密的一方使 ...

  8. c语言头文件中定义inline static相关函数的优劣

    头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-none-eabi-gcc下测试后得出结论. in ...

  9. 关于头文件中的 static inline函数

    关于头文件中的 static inline函数 头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-n ...

最新文章

  1. java 类 赋值_Java实现不同的类的属性之间相互赋值
  2. 设计模式(二)__装饰设计模式
  3. 对 COM 组件的调用返回了错误 HRESULT E_FAIL
  4. PHP封装的curl请求:有报错信息的 get post
  5. WinForm绘制柱形图
  6. java 蓝桥杯算法训练 最大值与最小值的计算(题解)
  7. 如何在Eclipse 3.6.2中安装swt/JFace
  8. adalm pluto_将Apache Pluto与Lucene搜索引擎示例教程集成
  9. 机器人走正方形c语言代码,张西臣---机器人走正方形
  10. python调用java接口或者类_python如何调用java类
  11. Centos中安装svnserver
  12. Android知识点 121 —— AlarmManager与RTC唤醒
  13. 【读书笔记】《认知语义学》序言
  14. Spring漫画学习笔记(一) 什么是BeanDefinition
  15. RT-thread实现USB虚拟U盘 模拟读卡器读写sd0
  16. 论文导读:CoAtNet是如何完美结合 CNN 和 Transformer的
  17. pycharm使用xshell+xming调用服务器图形界面
  18. 基于PHP MYsql的失物招领网站设计(附源码)
  19. 算法设计与分析----马的周游路线
  20. ELM327 Base Usage

热门文章

  1. c语言实现霍夫曼编码
  2. 工控服务器什么作用,工控服务器是什么
  3. DNS轮询+泛域名解析
  4. 胡莱三国2服务器维护,不想说再见《胡莱三国2》安卓首测完美收官
  5. MySQL 派生表(Derived Table)是什么
  6. 野樱桃树下的背叛 读后感
  7. MATLAB 将计算结果写入Excel表格中
  8. android+7.0+升级,终于来了!Android 7.0升级设备名单公布
  9. 《弃子长安》第十四章 弃子不公
  10. linux 更新字体