⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 co_sdo1.c

📁 在pic单片机上实现canopen协议通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
			case E_TRANSFER:					// Data cannot be transfered or stored to the application
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000020L;
				break;
	
			case E_LOCAL_CONTROL:				// Data cannot be transfered or stored to the application because of local control
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000021L;
				break;
			
			case E_DEV_STATE:					// Data cannot be transfered or stored to the application because of the device present state
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000022L;
				break;
	
		}
	}
}




/*********************************************************************
 * Function:        void _CO_COMM_SDO1_RXEvent(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the SDO1 receive event handler.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_SDO1_RXEvent(void)
{			
	// Process only if all 8 bytes of data are received
	if (mCANGetDataLen() == 8)
	{
		// Init the abort code to success
		_uSDO1ACode = E_SUCCESS;

		// Get the first byte of the received message
		_uSDO1Ctl.byte = mCANGetDataByte0();
		
		switch(_uSDO1Ctl.byte & 0xE0)
		{
			case 0x00:		// Download
				// Continue only if initiated and in download state
				if (_uSDO1State.bits.start)   	
				if (_uSDO1State.bits.dnld)
				{				
					// Compare the toggle bits. 
					if ((_uSDO1State.byte ^ _uSDO1Ctl.byte) & 0x10)	
					{
						// Reset states
						_uSDO1State.byte = 0;
						
						// abort, toggle not alternated
						_uSDO1ACode = E_TOGGLE;
						COMM_SDO_1_TF = 1;
						return;
					}	
									
					// Copy data from the driver 
					*((_DATA7*)(_uSDO1RxBuf + _uSDO1Dict.reqOffst)) = *((_DATA7*)(mCANGetPtrRxData() + 1));
										
					// Adjust the count or offset to the next segment
					_uSDO1Dict.reqOffst += (~_uSDO1Ctl.rctl.n) & 0x07; 	
					
					// If the count is greater than the object length then abort
					if (_uSDO1Dict.reqOffst > _uSDO1Dict.len)
					{
						// Reset states
						_uSDO1State.byte = 0;
						
						// Abort
						_uSDO1ACode = E_LEN_SERVICE;
						COMM_SDO_1_TF = 1;
						return;	
					}					
					
					// Set the next expected toggle
					_uSDO1State.bits.tog = ~_uSDO1State.bits.tog;
					
					// Set the header to respond, b'001t0000
					_uSDO1TxBuf[0] = (_uSDO1Ctl.byte | 0x20) & 0xF0;
					
					// Check for a complete flag
					if (_uSDO1Ctl.rctl.c)
					{
						// Set the pointer to the buffer
						_uSDO1Dict.pReqBuf = _uSDO1RxBuf;
						
						// Write the object
						mCO_DictObjectWrite(_uSDO1Dict);

						// Reset states
						_uSDO1State.byte = 0;

						// Send code, whatever was returned from the object
						_uSDO1ACode = mCO_DictGetRet();
						COMM_SDO_1_TF = 1;
					}
					else
					{
						// Queue to send acknowledge
						COMM_SDO_1_TF = 1;
					}
				}
				break;
				
				
				
				
			case 0x20:		// Initiate Download				
				// Kill the current start if any
				_uSDO1State.bits.start = 0;
		
				// Store the multiplexor locally
				_uSDO1TxBuf[1] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B0.byte = mCANGetDataByte1();
				_uSDO1TxBuf[2] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B1.byte = mCANGetDataByte2();
				_uSDO1TxBuf[3] = _uSDO1Dict.subindex = mCANGetDataByte3();
				
				// Preload potential reserved locations
				_uSDO1TxBuf[4] = 0;
				_uSDO1TxBuf[5] = 0;
				_uSDO1TxBuf[6] = 0;
				_uSDO1TxBuf[7] = 0;
				
				// Decode the object; this gets the data from the dictionary
				// If the object is functionally defined, then the data is retrieved 
				// from the object's defined function.
				mCO_DictObjectDecode(_uSDO1Dict);
				
				// Was the object in the dictionary
				if (mCO_DictGetRet() == E_SUCCESS)
				{					
					// Check the access for this request; must have write capability
					if (_uSDO1Dict.ctl & WR_BIT)  	
					{
						// Expedited download
						if (_uSDO1Ctl.ictl.e)
						{
							// If the count is specified, set the request length from the header
							if (_uSDO1Ctl.ictl.s) _uSDO1Dict.reqLen = (((~_uSDO1Ctl.ictl.n) & 0x03) + 1);
							
							// Otherwise set the length from the object
							else _uSDO1Dict.reqLen = _uSDO1Dict.len;
										
							if (_uSDO1Dict.reqLen == _uSDO1Dict.len)
							{
								// Reset states
								_uSDO1State.byte = 0;
																	
								// Set the pointer to the driver
								_uSDO1Dict.pReqBuf = mCANGetPtrRxData() + 4;
								
								// Call the object dictionary write function 
								mCO_DictObjectWrite(_uSDO1Dict);			
								
								// If the write was successful, queue to send acknowledge
								_uSDO1TxBuf[0] = 0x60;
	
								// Send abort, code returned from object
								_uSDO1ACode = mCO_DictGetRet();
									
								COMM_SDO_1_TF = 1;
							}
							else
							{
								// abort, data length does not match
								_uSDO1ACode = E_LEN_SERVICE;
								COMM_SDO_1_TF = 1;
							}
						}
						
						// Segmented download
						else 
						{							
							// If the count is specified
							if (_uSDO1Ctl.ictl.s) 
							{
								// Test the two upper most bytes, should be zero
								if (mCANGetDataByte6() | mCANGetDataByte7())
								{
									// Send abort, length does not match, 0607 0010
									_uSDO1ACode = E_LEN_SERVICE;
									COMM_SDO_1_TF = 1;	
									return;
								}
								
								// Compare the length against the object's defined length
								if (*((unsigned int *)(mCANGetPtrRxData() + 4)) != _uSDO1Dict.len)
								{
									// abort, data length does not match
									_uSDO1ACode = E_LEN_SERVICE;
									COMM_SDO_1_TF = 1;
									return;
								}
							}
							
							// Set the requested length
							_uSDO1Dict.reqLen = _uSDO1Dict.len;
														
							// Indicate a start download
							_uSDO1State.bits.start = 1;
							_uSDO1State.bits.dnld = 1;
							
							// First toggle should be 0
							_uSDO1State.bits.tog = 0;
							
							// Reset the data count 
							_uSDO1Dict.reqOffst = 0;	
							
							// Start the watchdog
							_uSDO1Timer = CO_SDO1_MAX_SEG_TIME;
							//_uSDO1State.bits.ntime = 0;
							
							// Queue to send acknowledge
							_uSDO1TxBuf[0] = 0x60;
							COMM_SDO_1_TF = 1;
						}
					}
					else
					{
						// abort, access problem	
						_uSDO1ACode = E_CANNOT_WRITE;
						COMM_SDO_1_TF = 1;
					}
				}
				
				// Object not found
				else 
				{
					// Abort, return the appropriate code
					_uSDO1ACode = mCO_DictGetRet();
					COMM_SDO_1_TF = 1;
				}
				break;
			
			
			
			
			case 0x40:		// Initiate Upload
				// Kill the current start
				_uSDO1State.bits.start = 0;
		
				// Store the multiplexor locally
				_uSDO1TxBuf[1] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B0.byte = mCANGetDataByte1();
				_uSDO1TxBuf[2] = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B1.byte = mCANGetDataByte2();
				_uSDO1TxBuf[3] = _uSDO1Dict.subindex = mCANGetDataByte3();
				
				// Preload potential reserved locations
				_uSDO1TxBuf[4] = 0;
				_uSDO1TxBuf[5] = 0;
				_uSDO1TxBuf[6] = 0;
				_uSDO1TxBuf[7] = 0;
				
				// Decode the object; this gets the data from the dictionary
				mCO_DictObjectDecode(_uSDO1Dict);
			
				// Check the return status from the decode
				if (mCO_DictGetRet() == E_SUCCESS)
				{									
					// Check the access for this request; must have read capability
					if (_uSDO1Dict.ctl & RD_BIT)  	
					{
						// Reset offset
						_uSDO1Dict.reqOffst = 0;
						
						// Reset states
						_uSDO1State.byte = 0;
						
						// If the object len is greater than 4 then segment upload
						if (_uSDO1Dict.len > 4)
						{															
							// Set the watchdog
							_uSDO1Timer = CO_SDO1_MAX_SEG_TIME;
							//_uSDO1State.bits.ntime = 0;
							
							// Indicate a start upload
							_uSDO1State.bits.start = 1;
							
							// Set pointer to internal buffer
							_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[4]);
														
							// Set the size of the object
							_uSDO1TxBuf[4] = ((UNSIGNED16 *)(&(_uSDO1Dict.len)))->bytes.B0.byte;
							_uSDO1TxBuf[5] = ((UNSIGNED16 *)(&(_uSDO1Dict.len)))->bytes.B1.byte;
							
							// Set the response command, size indicated
							_uSDO1TxBuf[0] = 0x41;
							
							// Queue to send acknowledge
							COMM_SDO_1_TF = 1;
						}
						
						// Expedited upload
						else
						{	
							// Set the length in the header
							switch ((unsigned char)(_uSDO1Dict.len))
							{
								case 1:	_uSDO1TxBuf[0] = 0x4F; break;
								case 2: _uSDO1TxBuf[0] = 0x4B; break;
								case 3: _uSDO1TxBuf[0] = 0x47; break;
								case 4: _uSDO1TxBuf[0] = 0x43; break;				
							}
									
							// Set the read length						
							_uSDO1Dict.reqLen = _uSDO1Dict.len;									
																															
							// Set the pointer to the transmit buffer
							_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[4]);
							
							// Read the data from the object into the buffer
							mCO_DictObjectRead(_uSDO1Dict);

							// Pass any codes
							_uSDO1ACode = mCO_DictGetRet();
							COMM_SDO_1_TF = 1;
						}
					}
					else
					{
						// abort, access problem		
						_uSDO1ACode = E_CANNOT_READ;
						COMM_SDO_1_TF = 1;
					}
				}
				
				// Object not found
				else 
				{
					// Abort, return the appropriate code
					_uSDO1ACode = mCO_DictGetRet();
					COMM_SDO_1_TF = 1;
				}
				break;
					
			
				
				
			
			case 0x60:		// Upload
				if (_uSDO1State.bits.start)	// Continue only if initiated
				if (!_uSDO1State.bits.dnld)	// and in a upload state
				{
					// Compare the toggle bits. 
					if ((_uSDO1State.byte ^ _uSDO1Ctl.byte) & 0x10)	
					{
						// Reset states
						_uSDO1State.byte = 0;

						// abort, toggle not alternated
						_uSDO1ACode = E_TOGGLE;
						COMM_SDO_1_TF = 1;
						return;
					}				
																															
					// Set the pointer to the transmit buffer
					_uSDO1Dict.pReqBuf = &(_uSDO1TxBuf[1]);
					
					// Set the offset
					_uSDO1BytesLeft.word = _uSDO1Dict.len - _uSDO1Dict.reqOffst;
							
					// If the data to be sent is less than 8 then set n and c
					if (_uSDO1BytesLeft.word > 7)
					{
						_uSDO1TxBuf[0] = 0x00; _uSDO1Dict.reqLen = 7;
					}
					else
					{
						// Reset states
						_uSDO1State.byte = 0;

						switch (_uSDO1BytesLeft.bytes.B0.byte)
						{
							case 1:		_uSDO1TxBuf[0] = 0x0D; _uSDO1Dict.reqLen = 1; break;
							case 2: 	_uSDO1TxBuf[0] = 0x0B; _uSDO1Dict.reqLen = 2; break;
							case 3: 	_uSDO1TxBuf[0] = 0x09; _uSDO1Dict.reqLen = 3; break;
							case 4: 	_uSDO1TxBuf[0] = 0x07; _uSDO1Dict.reqLen = 4; break;	
							case 5: 	_uSDO1TxBuf[0] = 0x05; _uSDO1Dict.reqLen = 5; break;
							case 6: 	_uSDO1TxBuf[0] = 0x03; _uSDO1Dict.reqLen = 6; break;
							case 7: 	_uSDO1TxBuf[0] = 0x01; _uSDO1Dict.reqLen = 7; break;
						}
					}
					
					// Setup the toggle
					if (~_uSDO1Ctl.rctl.t){((union _SDO_CTL *)(_uSDO1TxBuf))->rctl.t = 0;}
					else {((union _SDO_CTL *)(_uSDO1TxBuf))->rctl.t = 1;}
						
					// Read the data from the object into the transmit buffer
					mCO_DictObjectRead(_uSDO1Dict);
					
					// Adjust the offset
					_uSDO1Dict.reqOffst += _uSDO1Dict.reqLen;
					
					// Set the next expected toggle
					_uSDO1State.bits.tog = ~_uSDO1State.bits.tog;
			
					// Queue to send the data
					_uSDO1ACode = mCO_DictGetRet();
					COMM_SDO_1_TF = 1;
				}
				break;
				
				
			
			case 0x80:		// Abort Request
				// Reset SDO states
				_uSDO1State.byte = 0;
				break;
				
				
				
			default:
				// Send abort, not a valid command	
				_uSDO1ACode = E_CS_CMD;	
				COMM_SDO_1_TF = 1;
				break;
		}
	}
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -