DMA+USART+stm32

众所周知,串口是按照字节传输的,每一次传输一个字节。要传一帧数据,需要按照协议,帧头,帧尾,长度等信息,从字节流里面去分离。或者按照超时去分离。

STM32里面提供了DMA传输方式,整个过程有硬件控制。不占用处理器时间,高效。

发包:采用DMA方式,DMA发包完成会生成一个DMA发包完成中断。

收包:采用DMA+串口空闲中断方式,DMA空闲中断在,收到串口数据,串口空闲1个字节,自动触发。

代码如下:

第一步:引脚和时钟初始化

  1. void GPIO_Configuration(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. /* 使能USART1 时钟和所在端口时钟 */
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  7. /*初始化USART1_TX端口*/
  8. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOA, &GPIO_InitStructure);
  12. /*初始化USART1_RX端口 */
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  15. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16. GPIO_Init(GPIOA, &GPIO_InitStructure);
  17. /* 使能USART2时钟和USART2所占用引脚的时钟 */
  18. //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  19. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  20. /* 初始化USART2_Tx时钟 */
  21. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  22. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  23. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  24. GPIO_Init(GPIOA, &GPIO_InitStructure);
  25. /* 初始化USART2_Rx时钟 */
  26. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  28. GPIO_Init(GPIOA, &GPIO_InitStructure);
  29. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  30. GPIO_Init(GPIOA, &GPIO_InitStructure);
/*初始化RS485引脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( GPIOA, & GPIO_InitStructure );
  1. }

第二步:串口配置

  1. void USART_Configuration(void)
  2. {
  3. USART_InitTypeDef USART_InitStructure;
  4. /* USART1 115200 n 8 1 */
  5. USART_InitStructure.USART_BaudRate = 115200;
  6. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  7. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  8. USART_InitStructure.USART_Parity = USART_Parity_No;
  9. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  10. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  11. USART_Init(USART1, &USART_InitStructure);
  12. //开串口空闲中断
  13. USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);
  14. //使能USART1
  15. USART_Cmd(USART1, ENABLE);
  16. USART_ClearFlag(USART1, USART_FLAG_TC);
  17. /*usart2 115200 n 8 1*/
  18. USART_InitStructure.USART_BaudRate = 115200;
  19. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  20. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  21. USART_InitStructure.USART_Parity = USART_Parity_No;
  22. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  23. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  24. USART_Init(USART2, &USART_InitStructure);
  25. //开串口空闲中断
  26. USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);
  27.     //使能USART2
  28. USART_Cmd(USART2, ENABLE);
  29. USART_ClearFlag(USART2, USART_FLAG_TC);
  30. }

第三步:DMA设置

  1. void DMA_Configuration(void)
  2. {
  3. DMA_InitTypeDef DMA_InitStructure;
  4. /* DMA clock enable */
  5. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1
  6. /* DMA1 Channel4 (triggered by USART1 Tx event) Config */
  7. DMA_DeInit(DMA1_Channel4);
  8. DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
  9. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_SEND_DATA;
  10. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  11. DMA_InitStructure.DMA_BufferSize = 128;
  12. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  13. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  14. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  15. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  16. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  17. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  18. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  19. DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  20. DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
  21. DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);
  22. /* Enable USART1 DMA TX request */
  23. USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
  24. DMA_Cmd(DMA1_Channel4, DISABLE);
  25. /* DMA1 Channel7 (triggered by USART2 Tx event) Config */
  26. DMA_DeInit(DMA1_Channel7);
  27. DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
  28. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_SEND_DATA;
  29. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  30. DMA_InitStructure.DMA_BufferSize = 128;
  31. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  32. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  33. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  34. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  35. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  36. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  37. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  38. DMA_Init(DMA1_Channel7, &DMA_InitStructure);
  39. DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
  40. DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);
  41. /* Enable USART1 DMA TX request */
  42. USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
  43. DMA_Cmd(DMA1_Channel7, DISABLE);
  44. /* DMA1 Channel5 (triggered by USART1 Rx event) Config */
  45. DMA_DeInit(DMA1_Channel5);
  46. DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
  47. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RECEIVE_DATA;
  48. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  49. DMA_InitStructure.DMA_BufferSize = 128;
  50. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  51. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  52. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  53. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  54. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  55. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  56. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  57. DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  58. DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  59. DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);
  60. /* Enable USART1 DMA RX request */
  61. USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
  62. DMA_Cmd(DMA1_Channel5, ENABLE);
  63. /* DMA1 Channel6 (triggered by USART1 Rx event) Config */
  64. DMA_DeInit(DMA1_Channel6);
  65. DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
  66. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RECEIVE_DATA;
  67. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  68. DMA_InitStructure.DMA_BufferSize = 128;
  69. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  70. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  71. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  72. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  73. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  74. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  75. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  76. DMA_Init(DMA1_Channel6, &DMA_InitStructure);
  77. DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
  78. DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);
  79. /* Enable USART2 DMA RX request */
  80. USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
  81. DMA_Cmd(DMA1_Channel6, ENABLE);
  82. }

第四步:NVIC中断配置

  1. void NVIC_Configuration(void)
  2. {
  3. NVIC_InitTypeDef NVIC_InitStructure;
  4. /* Configure one bit for preemption priority */
  5. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  6. /* Enable the USART1 Interrupt串口空闲中断 */
  7. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  8. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  9. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  10. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  11. NVIC_Init(&NVIC_InitStructure);
  12. /* Enable the USART2 Interrupt 串口空闲中断 */
  13. NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  14. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  15. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  16. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  17. NVIC_Init(&NVIC_InitStructure);
  18. //Enable DMA Channel4 Interrupt DMA 发包完成中断
  19. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
  20. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  21. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  22. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  23. NVIC_Init(&NVIC_InitStructure);
  24. //Enable DMA Channel7 Interrupt DMA 发包完成中断
  25. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
  26. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  27. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  28. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  29. NVIC_Init(&NVIC_InitStructure);
  30. }

第五步:串口空闲中断配置

  1. void USART1_IRQHandler(void)
  2. {
  3. u16 DATA_LEN;
  4. if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//收包完成,触发空闲中断
  5. {
  6. DMA_Cmd(DMA1_Channel5, DISABLE);//关掉DMA防干扰
  7. DATA_LEN=128-DMA_GetCurrDataCounter(DMA1_Channel5); //计算长度
  8. if(DATA_LEN > 0)
  9. {
  10. //数据处理
  11. }
  12. DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清楚中断标志位,方便下一次接收
  13. DMA1_Channel5->CNDTR = 128;//
  14. USART1->SR;
  15. USART1->DR;
  16. DMA_ClearITPendingBit(DMA1_IT_TC5);
  17. DMA_ClearITPendingBit(DMA1_IT_TE5);
  18. DMA_Cmd(DMA1_Channel5, DISABLE);//
  19. DMA1_Channel5->CNDTR = 128;//?
  20. DMA_Cmd(DMA1_Channel5, ENABLE);//
  21. }
  22. if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//
  23. {
  24. USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);
  25. }
  26. USART_ClearITPendingBit(USART1, USART_IT_TC);
  27. USART_ClearITPendingBit(USART1, USART_IT_IDLE);
  28. }
  29. void USART2_IRQHandler(void)
  30. {
  31. u16 DATA_LEN;
  32. if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //?????????
  33. {
  34. DMA_Cmd(DMA1_Channel6, DISABLE);
  35. DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6);
  36. if(DATA_LEN > 0)
  37. {
  38. }
  39. //DMA_Cmd(DMA1_Channel5, DISABLE);//??DMA,?????????
  40. DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//???
  41. DMA1_Channel6->CNDTR = 512;//???
  42. DMA_Cmd(DMA1_Channel6, ENABLE);//???,??DMA
  43. //?SR??DR??Idle
  44. USART2->SR;
  45. USART2->DR;
  46. DMA_ClearITPendingBit(DMA1_IT_TC6);
  47. DMA_ClearITPendingBit(DMA1_IT_TE6);
  48. DMA_Cmd(DMA1_Channel6, DISABLE);//
  49. DMA1_Channel6->CNDTR = 128;//?
  50. DMA_Cmd(DMA1_Channel6, ENABLE);//
  51. }
  52. if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//??
  53. {
  54. USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);
  55. }
  56. USART_ClearITPendingBit(USART2, USART_IT_TC);
  57. USART_ClearITPendingBit(USART2, USART_IT_IDLE);
  58. }

第六步:DMA发包

  1. void usart1_DMA_send_data(int DATA_LEN)
  2. {
  3. DMA_Cmd(DMA1_Channel4, DISABLE);
  4. DMA1_Channel4->CNDTR=DATA_LEN; //DMA1
  5. DMA_Cmd(DMA1_Channel4, ENABLE);
  6. }
  7. void usart2_DMA_send_data(int DATA_LEN)
  8. {
  9. DMA_Cmd(DMA1_Channel7, DISABLE); //
  10. DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,?????
  11. DMA_Cmd(DMA1_Channel7, ENABLE);
  12. }

第7步: 配置发包完成中断

  1. //DMA1_Channel4
  2. void DMA1_Channel4_IRQHandler(void)
  3. {
  4. DMA_ClearITPendingBit(DMA1_IT_TC4);
  5. DMA_ClearITPendingBit(DMA1_IT_TE4);
  6. DMA_Cmd(DMA1_Channel4, DISABLE);//
  7. }
  8. //DMA1_Channel7
  9. void DMA1_Channel7_IRQHandler(void)
  10. {
  11. DMA_ClearITPendingBit(DMA1_IT_TC7);
  12. DMA_ClearITPendingBit(DMA1_IT_TE7);
  13. DMA_Cmd(DMA1_Channel7, DISABLE);
  14. }

第8步:RS485首发引脚配置

  1. void set_RS485_TX_mode()
  2. {
  3. int cnt = 72000;
  4. PAout(8) =1;
  5. while(cnt--);
  6. }
  7. void set_RS485_Rx_mode()
  8. {
  9. int cnt = 72000;
  10. while(cnt--);
  11. PAout(8) =0;
  12. }

第9步 DMA发包封装:

  1. void rs485_DMA_send_data(uint8_t* data,uint8_t size)
  2. {
  3. set_RS485_TX_mode();
  4. memcpy(USART1_SEND_DATA,data,size);
  5. usart1_DMA_send_data(size);
  6. set_RS485_Rx_mode();
  7. }
  8. void USART_DMA_send_data(uint8_t* data,uint8_t size)
  9. {
  10. memcpy(USART2_SEND_DATA,data,size);
  11. usart2_DMA_send_data(size);
  12. }

以上就是全部的API。经测试收发数据都正常。

null

时间: 2024-08-18 04:23:39

DMA+USART+stm32的相关文章

DMA(STM32)

1.DMA:data memory access //实际的内存存储 注:DMA干活的时候是不需要CPU干涉的 2. ①内存(定义的变量)---外设(寄存器): ②内存---内存 ③外设---外设(一个外设的寄存器到另一个外设的寄存器) 3. STM32有两个DMA控制器 如图: 4.举例说明:(内存到外设,串口1 TX DMA) 1 void USART1_DMA_Config(void) 2 { 3 DMA_InitTypeDef DMA_InitStructure; 4 5 /*Open

STM32 F407VG (二)DMA

根据ST公司提供的相关信息,DMA是STM32中一个独立与Cortex-M4核的模块:主要功能是通信"桥梁"的作用,可以将所有外设寄存器和内存空间"连接"起来,这样就可以高速问各寄存器,其传输不受CPU的支配,其间的通讯不占CPU资源,访问速度高,传输还是双向的(双AHB主总线结构):它可以将外设寄存器中的数据与储存器中变量建立绑定,还可以将一外设的寄存器或缓冲器与另外设的寄存器或缓冲器建立双向通讯. 1.DMA初始化 DMA_Init(DMAx_Streamy,

串口通讯(DMA模式)

在高级语言中,I/O 流输入(input)操作一般都要求指定要读取的数据的最大长度(字节数).当接收到至少1字节.最多所指定的字节数时,函数返回. STM32 串口接收数据时,HAL API 要求指定数据长度.但无论轮询.中断或是DMA方式,都必须完整地接收到这么多字节,程序流程才继续.如何接收变长消息,我想不到特别好的实现方式.一种方式是,轮询加超时.另一种方式是,设计消息协议,使消息头为定长,且消息头内包含消息体的长度.但是,如果通讯异常,导致消息数据错误或丢失,那么,还是缺少"提前返回&q

STM32的USART使用DMA接收带校验位的数据

工作中用到了一个数据包里面的数据采用不同的校验方式,一部分为奇校验,一部分为偶校验.这时我的方案为: 1.USART设置9bit数据长度,1个停止位,无校验位,这时确保能接收到带校验位的数据 2.设置DMA接收和发送数据,设置外设地址和内存地址都为halfword(16bit)可以接收到带校验位的数据包. 3.然后通过软件来校验接收到的数据 4.由于设置了无校验位,那么此时用发送的数据必须加上软件计算出的校验位发送

STM32学习笔记——USART串口(向原子哥和火哥学习)

一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择. STM32 的串口资源相当丰富的,功能也相当强劲.STM32F103ZET6 最多可提供 5 路串口,有分数波特率发生器,支持同步单向通信和半双工单线通信,支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作.它还允许多处理器通信.

stm32 DMA数据搬运 [操作寄存器+库函数](转)

源:stm32 DMA数据搬运 [操作寄存器+库函数] DMA(Direct Memory Access)常译为“存储器直接存取”.早在Intel的8086平台上就有了DMA应用了. 一个完整的微控制器通常由CPU.存储器和外设等组件构成.这些组件一般在结构和功能上都是独立的,而各个组件的协调和交互就由CPU完成.如此一来,CPU作为整个芯片的核心,其处理的工作量是很大的.如果CPU先从A外设拿到一个数据送给B外设使用,同时C外设又需要D外设提供一个数据...这样的数据搬运工作将使CPU的负荷显

STM32外设DMA使用总结

STM32外设DMA使用总结: 1.根据需要选择DAM模式: (1)循环模式-DMA_Mode =  DMA_Mode_Circular (2)正常模式-DMA_Mode =  DMA_Mode_Normal 2.对于DMA1的Chanel3,对应外设为USART3的RX 试想:如果串口接收中断和DAM中断同时打开,CPU如何相应? (1)中断优先级不同:这好说,支持嵌套中断(NVIC)的Cortex-M3自然优先服务中断优先级高的 (2)中断优先级相同:处理原则,先来先处理:若同时到来,中断号

STM32之usart

1.uart与usart的区别 UART:universal asynchronous receiver and transmitter 通用 异步 接收 发送 [总线信号] TX , RX USART:universal synchronous asynchronous receiver and transmitter 通用 同步 异步 接收 发送 [总线信号] TX, RX, CK 总体来说,usart只是比uart多了一个同步信号,usart可以使用同步方式进行信息的收发 同步传输与异步传

关于STM32 USART(串口)发送数据丢失第一帧的真实原因探索

自我介绍 为什么要写个自我介绍?俗话说,光说不练假把式,光练不说傻把式, 因为本人一直很自负,感觉什么东西都可以很快上手(当然非对口专业知识要求高的技能除外),如果我不把这自负表现出来,感觉会憋出内伤. 本人于2015年毕业于电子科技大学,开始的理想是进入一家国外的游戏公司,但理想很丰满,现实很骨感,给育碧.2k Game.Gameloft.EA都投了简历,但都被无情pass掉了(在此吐槽一下,这些公司真的是想在校园里招本科生吗?明明是研究生的计算机图形学却成了这些公司对本科生的要求).后来毕业